Index: sources/ApplicationController.cpp =================================================================== diff -u -rbb74da05f81b82dad3ec844c1feb1135b949f1c2 -r142f2ddb8ce284c52c0add2acf3ac81f471b78de --- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision bb74da05f81b82dad3ec844c1feb1135b949f1c2) +++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 142f2ddb8ce284c52c0add2acf3ac81f471b78de) @@ -1,38 +1,42 @@ /*! * - * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * - * \file ApplicationController.cpp - * \author (last) Peter Lucia - * \date (last) 25-Jun-2020 - * \author (original) Behrouz NematiPour - * \date (original) 24-Sep-2019 + * \file ApplicationController.cpp + * \author (last) Behrouz NematiPour + * \date (last) 28-Sep-2022 + * \author (original) Behrouz NematiPour + * \date (original) 26-Aug-2020 * */ #include "ApplicationController.h" // Qt +#include // Project #include "MainTimer.h" #include "MessageDispatcher.h" #include "Logger.h" -#include "DriveWatcher.h" -#include "FileHandler.h" +#include "DeviceController.h" +//#include "FileHandler.h" #include "GuiController.h" +#include "Settings.h" +#include "MSettings.h" +#include "WifiInterface.h" +#include "BluetoothInterface.h" /*! * \brief ApplicationController::ApplicationController * \details Constructor * \param parent - QObject parent owner object. * Qt handles the children destruction by their parent objects life-cycle. */ -ApplicationController::ApplicationController(QObject *parent) : QObject(parent) -{ - _applicationPost = new ApplicationPost(this); +ApplicationController::ApplicationController(QObject *parent) : QObject(parent) { + _post.setParent(this); } /*! @@ -44,10 +48,7 @@ _init = true; initConnections(); - // coco begin validated: The class ApplicationPost has not been implemented Yet. - if (!_applicationPost->init()) return false; - // coco end - LOG_EVENT("UI," + tr("%1 Initialized").arg(metaObject()->className())); + LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className())); return true; } @@ -74,11 +75,11 @@ */ void ApplicationController::quit() { - // coco begin validated: Application termination is not correctly done in coco!!! + // disabled coco begin validated: Application termination is not correctly done in coco!!! // it has been tested and works perfectly fine in normal run. quitThread(); // validated } -// coco end +// disabled coco end /*! * \brief ApplicationController::initConnections @@ -87,6 +88,19 @@ */ void ApplicationController::initConnections() { + + connect(&_post , SIGNAL( didWiFi (bool)), + this , SLOT(onPOSTWiFi (bool))); + connect(&_post , SIGNAL( didBluetooth(bool)), + this , SLOT(onPOSTBluetooth(bool))); + connect(&_post , SIGNAL( didCloudSync(bool)), + this , SLOT(onPOSTCloudSync(bool))); + + connect(&_post , SIGNAL( didFail (Gui::GuiAlarmID )), + this , SLOT(onPOSTFail (Gui::GuiAlarmID ))); + connect(&_post , SIGNAL( didDone (bool )), + this , SLOT (onPOSTDone (bool ))); + connect(&_MainTimer , SIGNAL( didTimeout()), this , SLOT(onMainTimerTimeout())); @@ -102,24 +116,45 @@ this , SLOT( onFailedTransmit(Sequence))); // USB drive - connect(&_GuiController , SIGNAL(didUSBDriveUmount()), - this , SLOT( onUSBDriveUmount())); - connect(&_DriveWatcher , SIGNAL(didUSBDriveMount ()), - this , SLOT( onUSBDriveMount ())); - connect(&_DriveWatcher , SIGNAL(didUSBDriveRemove()), - this , SLOT( onUSBDriveRemove())); + connect(&_GuiController , SIGNAL(didUSBDriveUmount()), + this , SLOT( onUSBDriveUmount())); + connect(&_DeviceController , SIGNAL(didUSBDriveMount ()), + this , SLOT( onUSBDriveMount ())); + connect(&_DeviceController , SIGNAL(didUSBDriveRemove()), + this , SLOT( onUSBDriveRemove())); + connect(&_DeviceController , SIGNAL(didUSBSpaceChange(bool, qint64, qint64, quint8)), + this , SLOT( onUSBSpaceChange(bool, qint64, qint64, quint8))); // SD Card - connect(&_DriveWatcher , SIGNAL(didSDCardStateChange(bool, bool)), - this , SLOT( onSDCardStateChange(bool, bool))); + connect(&_DeviceController , SIGNAL(didSDCardStateChange(bool, bool)), + this , SLOT( onSDCardStateChange(bool, bool))); + connect(&_DeviceController , SIGNAL(didSDCardSpaceChange(bool, qint64, qint64, quint8)), + this , SLOT( onSDCardSpaceChange(bool, qint64, qint64, quint8))); + connect(&_DeviceController , SIGNAL(didSDCardSpaceTooLow(quint8)), + this , SLOT( onSDCardSpaceTooLow(quint8))); + connect(&_GuiController , SIGNAL(didExportLog (const GuiStringIndexMap &)), + this , SLOT( onExportLog (const GuiStringIndexMap &))); + connect(&_GuiController , SIGNAL(didExportService (const GuiStringIndexMap &)), + this , SLOT( onExportService (const GuiStringIndexMap &))); + connect(&_GuiController , SIGNAL(didExportTreatment (const GuiStringIndexMap &)), + this , SLOT( onExportTreatment (const GuiStringIndexMap &))); - connect(&_GuiController , SIGNAL(didExportLog()), - this , SLOT( onExportLog())); + connect(&_Logger , SIGNAL(didExportLogs ()), + this , SLOT( onExport ())); + connect(&_Logger , SIGNAL(didExportStat (quint32, const QString &, quint8)), + this , SLOT( onExportStat (quint32, const QString &, quint8))); - connect(&_Logger , SIGNAL(didExportLogs()), - this , SLOT( onExport())); + // Settings - move to application thread + connect(this, SIGNAL(didSettingsInit()), + this, SLOT( onSettingsInit())); + connect(&_settingsWatcher, SIGNAL(finished ()), + this , SLOT(onSettingsUpdate())); + + // Device Signal/Slots + DEVICE_APP_INIT_CONNECTIONS_LIST + // ---- Signal/Slots ADJUST_TRANSMT_MODEL_BRIDGE_CONNECTIONS(_GuiController ) ACTION_RECEIVE_MODEL_BRIDGE_CONNECTIONS(_MessageDispatcher) @@ -135,7 +170,7 @@ void ApplicationController::initThread(QThread &vThread) { // runs in main thread - Q_ASSERT_X(QThread::currentThread() == qApp->thread() , __func__, "The Class initialization must be done in Main Thread" ); + Q_ASSERT_X(QThread::currentThread() == qApp->thread(), __func__, "The Class initialization must be done in Main Thread" ); _thread = &vThread; _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className())); connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit())); @@ -145,20 +180,20 @@ /*! * \brief ApplicationController::quitThread - * \details Moves this object to main thread to be handled by QApplicaiton + * \details Moves this object to main thread to be handled by QApplication * And to be destroyed there. */ void ApplicationController::quitThread() { - // coco begin validated: Application termination is not correctly done in coco!!! + // disabled coco begin validated: Application termination is not correctly done in coco!!! // it has been tested and works perfectly fine in normal run. if ( ! _thread ) return; // runs in thread moveToThread(qApp->thread()); // validated } -// coco end +// disabled coco end /*! * \brief ApplicationController::onFailedTransmit @@ -205,82 +240,120 @@ /*! * \brief ApplicationController::onUSBDriveMount - * \details This is the slot which connects to the _DriveWatcher didUSBDriveMount signal + * \details This is the slot which connects to the _DeviceController didUSBDriveMount signal * and notifies the other classes (GuiController) by emitting its signal didUSBDriveMount */ void ApplicationController::onUSBDriveMount () { - // coco begin validated: This needs user interaction to plug-in USB device + // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually emit didUSBDriveMount(); } -// coco end +// disabled coco end /*! * \brief ApplicationController::onUSBDriveRemove * \details This is the slot which connects to the _GuiController didUSBDriveUmount signal - * and notifies the other classes (DriveWatcher) by emitting its signal didUSBDriveUmount + * and notifies the other classes (DeviceController) by emitting its signal didUSBDriveUmount */ void ApplicationController::onUSBDriveUmount() { - // coco begin validated: This needs user interaction to plug-in USB device + // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually emit didUSBDriveUmount(); } -// coco end +// disabled coco end /*! * \brief ApplicationController::onUSBDriveRemove - * \details This is the slot which connects to the _DriveWatcher didUSBDriveRemove signal + * \details This is the slot which connects to the _DeviceController didUSBDriveRemove signal * and notifies the other classes (GuiController) by emitting its signal didUSBDriveRemove */ void ApplicationController::onUSBDriveRemove() { - // coco begin validated: This needs user interaction to plug-in USB device - // has been tested manually emit didUSBDriveRemove(); } -// coco end +void ApplicationController::onUSBSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent) +{ + //DEBUG:0: qDebug() << "ApplicationController::onUSBSpaceChange" << vReady << vTotal << vAvailable << vPercent; + emit didUSBSpaceChange(vReady, vTotal, vAvailable, vPercent); +} + /*! * \brief ApplicationController::onSDCardStateChange - * \details This is the slot which connects to the _DriveWatcher didSDCardStateChange signal + * \details This is the slot which connects to the _DeviceController didSDCardStateChange signal * and notifies the other classes (GuiController) by emitting its signal didSDCardStateChange * \param vIsReady - SDCard is Ready * \param vIsReadOnly - SDCard is ReadOnly */ void ApplicationController::onSDCardStateChange(bool vIsReady, bool vIsReadOnly) { - // coco begin validated: This needs user interaction to plug-in SD Card - // has been tested manually + //DEBUG:0: qDebug() << " ***** ApplicationController " << Storage::SDCard_Base_Path_Name << vIsReady; emit didSDCardStateChange(vIsReady, vIsReadOnly); } -// coco end +void ApplicationController::onSDCardSpaceChange(bool vReady, qint64 vTotal, qint64 vAvailable, quint8 vPercent) +{ + emit didSDCardSpaceChange(vReady, vTotal, vAvailable, vPercent); +} + /*! + * \brief ApplicationController::onSDCardSpaceTooLow + * \details The handler slot for the didSDCardSpaceTooLow signal comes form DeviceController + * \param vAvailablePercent - the minimum limit of available storage space + */ +void ApplicationController::onSDCardSpaceTooLow(quint8 vAvailablePercent) +{ + // disabled coco begin validated: This needs user interaction to plug-in SD Card + // has been tested manually + emit didSDCardSpaceTooLow(vAvailablePercent); +} +// disabled coco end + +/*! * \brief ApplicationController::onExportLog * \details the slot which will be called by UI to so the log export. */ -void ApplicationController::onExportLog() +void ApplicationController::onExportLog(const GuiStringIndexMap &vExportList) { - // coco begin validated: This needs user interaction to plug-in USB device - // has been tested manually - LOG_EXPORT; + LOG_EXPORTLOG(vExportList); } -// coco end +/*! + * \brief ApplicationController::onExportService + * \details the slot which will be called by UI to do the service log export. + */ +void ApplicationController::onExportService(const GuiStringIndexMap &vExportList) +{ + LOG_EXPORTERR(vExportList); +} +/*! + * \brief ApplicationController::onExportTreatment + * \details the slot which will be called by UI to do the treatment treatment log export. + */ +void ApplicationController::onExportTreatment(const GuiStringIndexMap &vExportList) +{ + LOG_EXPORTTRT(vExportList); +} /*! * \brief ApplicationController::onExport * \details the slot which will be called by logger is done exporting. */ void ApplicationController::onExport() { - // coco begin validated: This needs user interaction to plug-in USB device + // disabled coco begin validated: This needs user interaction to plug-in USB device // has been tested manually emit didExport(); } -// coco end +void ApplicationController::onExportStat(quint32 vIndex, const QString &vFileName, quint8 vPercent) +{ + // DEBUG: qDebug() << "1" << vIndex << vFileName << vPercent; + emit didExportStat(vIndex, vFileName, vPercent); +} +// disabled coco end + /*! * \brief ApplicationController::keepAlive * \details This is the message which has to be send over the CANBus @@ -297,11 +370,12 @@ if (mFakeDataLen) { if (gFakeSeqAtBegin) { createFakeSeqAtBeginLongMessage(mData, mFakeDataLen); - } else { + } + else { createFakeSequencedLongMessage (mData, mFakeDataLen); } } - // coco end + // disabled coco end else { mData += static_cast(GuiActionData::NoData); } @@ -317,14 +391,14 @@ */ void ApplicationController::createFakeSequencedLongMessage(QVariantList &vData, const int vFakeDataLen) { - // coco begin validated: This is a fake data generator for CANBus missing/swapped frames Testing + // disabled coco begin validated: This is a fake data generator for CANBus missing/swapped frames Testing // will never be executed on the product // has been tested manually QByteArray data; if (vFakeDataLen == 1 && gFakeData == QByteArray::fromHex(gFakeData_default)) { static quint16 txCount = 0; Types::U16 seq; - quint8 dataBytesLeft = 0; + quint8 dataBytesLeft = 0; const quint8 crcBytesLen = 2; for (int i = 0; i < 13; i++) { switch (i) { @@ -358,11 +432,12 @@ Types::safeIncrement(txCount); } vData += QByteArray::fromHex(data.toHex()); - } else { + } + else { vData += gFakeData; } } -// coco end +// disabled coco end /*! * \brief ApplicationController::createFakeSequencedAtBeginLongMessage @@ -372,14 +447,14 @@ */ void ApplicationController::createFakeSeqAtBeginLongMessage(QVariantList &vData, const int vFakeDataLen) { - // coco begin validated: This is a fake data generator for CANBus missing/swapped frames Testing + // disabled coco begin validated: This is a fake data generator for CANBus missing/swapped frames Testing // will never be executed on the product // has been tested manually QByteArray data; if (vFakeDataLen == 1 && gFakeData == QByteArray::fromHex(gFakeData_default)) { static quint32 txCount = 0; Types::U32 seq; - quint8 dataBytesLeft = 0; + quint8 dataBytesLeft = 0; const quint8 crcBytesLen = 2; for (int i = 0; i < 13; i++) { switch (i) { @@ -414,13 +489,137 @@ data += (char)(0); } break; - } Types::safeIncrement(txCount); } vData += QByteArray::fromHex(data.toHex()); - } else { + } + else { vData += gFakeData; } } -// coco end +// disabled coco end + +/*! + * \brief ApplicationController::initSettings + * \details The external method available to request for initializing the settings + * To start the task in Application Tread, emits a signal which will call a slot to take care of the execution. + */ +void ApplicationController::initSettings() +{ + // this emit guaranties that the slot will be called in the application thread + // also the signal is private so it will be used internally only. + emit didSettingsInit({}); +} + +/*! + * \brief ApplicationController::onSettingsInit + * \details The slot which will be called to start the settings initialization in Application thread. + * This method also initializes the Settings model singleton object to let it live in the Application thread. + * To start the setting initialization QConcurrent is used with QFuture to signal the Application when it's done. + */ +void ApplicationController::onSettingsInit() +{ + // That is enough to call to the I function here to create the object in the thread that Settings is leaving in, + // which currently is Application_Thread, since the Settings is created in that thread. + _Settings; + + QFuture mFuture = QtConcurrent::run(this, &ApplicationController::settingsInit); + _settingsWatcher.setFuture(mFuture); +} + +/*! + * \brief onSettingsUpdate + * \details when the Settings reads the .conf files and fills the MSettings emits this finished signal + * then this slot is called to notify the GuiController about the settings that being ready. + */ +void ApplicationController::onSettingsUpdate() +{ + onActionReceive(SettingsData()); + + // call initialization functions when setting's ready. + _Settings.datetimeFormat(); + + emit didSettingsDone(); +} + +/*! + * \brief ApplicationController::onPOSTWiFi + * \details Starts the WiFi Interface + */ +void ApplicationController::onPOSTWiFi(bool vPass) { + if (vPass) { + _WifiInterface.doStart(); + } + emit didPOSTWiFi(vPass); +} + +/*! + * \brief ApplicationController::onPOSTBluetooth + * \details Starts the Bluetooth Interface + */ +void ApplicationController::onPOSTBluetooth(bool vPass) { + if (vPass) { + _BluetoothInterface.valid(true); + _BluetoothInterface.doStart(); + } + else { + _BluetoothInterface.doNotifyStatePOSTError(); + emit didPOSTBluetooth(vPass); + } +} + +/*! + * \brief ApplicationController::onPOSTCloudSync + * \details Notifies the CloudSync POST status + */ +void ApplicationController::onPOSTCloudSync(bool vPass) +{ + emit didPOSTCloudSync(vPass); +} + +/*! + * \brief ApplicationController::onPOSTFail + * \details sends the Alarm Trigger message, used when the POST Failed. + * \param vAlarmID + */ +void ApplicationController::onPOSTFail(GuiAlarmID vAlarmID) { + emit didActionTransmit(GuiActionType::ID_AlarmTriggered, {vAlarmID ,0,0,0,0,0,0,0}); +} + +/*! + * \brief ApplicationController::onPOSTDone + * \details Sends the POST Final message + */ +void ApplicationController::onPOSTDone(bool vPass) { + AdjustUIPostFinalResultRequestData data; + data.mResult = vPass; + emit didAdjustment(data); + LOG_DEBUG("ApplicationPost Done"); +} + +/*! + * \brief ApplicationController::settingsInit + * \details The Settings read function is called in this method. + * This callback function for the QCuncurrnent run. + */ +void ApplicationController::settingsInit() +{ + Storage::Settings settings; + settings.read(); +} + +/*! + * \brief ApplicationController::onstartPOST + * \details The POST entry point + * - Sends the first async check-in to the HD to let HD know it can start it's POST and UI is ready to communicate. + * - Connects to the POST process to be able to trigger an alarm during the POST to be listed in the active alarms list. + * - Connects to the POST process to be able to send the final UI POST result. + * - Starts the UI POST + * \return void + */ +void ApplicationController::onstartPOST() { + LOG_DEBUG("ApplicationPost Start"); + emit didActionTransmit(GuiActionType::ID_KeepAlive, {}); + _post.start(); +}