Index: sources/ApplicationController.cpp =================================================================== diff -u -r689177edf29dee6f10bebfed42f6bbadeb7ce8a8 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 689177edf29dee6f10bebfed42f6bbadeb7ce8a8) +++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -89,7 +89,6 @@ */ void ApplicationController::initConnections() { - connect(&_post , SIGNAL( didEthernet (bool)), this , SLOT(onPOSTEthernet (bool))); connect(&_post , SIGNAL( didWiFi (bool)), @@ -112,6 +111,8 @@ this , SLOT( onActionTransmit(GuiActionType, const QVariantList &))); connect(&_GuiController , SIGNAL(didQuitApplication()), this , SLOT( onQuitApplication())); + connect(&_GuiController , SIGNAL(didTreatmentRangesDone(bool)), + this , SLOT( onTreatmentRangesDone(bool))); // From HD/DG connect(&_MessageDispatcher, SIGNAL(didActionReceive(GuiActionType, const QVariantList &)), @@ -159,7 +160,6 @@ connect(&_settingsWatcher, SIGNAL(finished ()), this , SLOT(onSettingsUpdate())); - // Device Signal/Slots DEVICE_APP_INIT_CONNECTIONS_LIST @@ -528,10 +528,10 @@ // which currently is Application_Thread, since the Settings is created in that thread. _Settings; - QFuture mFuture = QtConcurrent::run([=](){ // made the call a lambda to make sure there is no function to accidentally being called, out of thread [developer safety]. + QFuture mFuture = QtConcurrent::run( [=]() -> int { // made the call a lambda to make sure there is no function to accidentally being called, out of thread [developer safety]. //TODO The Settings shall be the Singleton SettingsController and modify the MSettings like the others. Storage::Settings settings; - settings.read(); + return settings.read(); }); _settingsWatcher.setFuture(mFuture); } @@ -546,16 +546,21 @@ onActionReceive(SettingsData()); /// POST /// - // call initialization functions when setting's ready. - _Settings.datetimeFormat(); - emit didSettingsDone( ); // MessageDispatcher -> MessageInterpreter : updateUnhandledMessages - emit didPOSTPass (_post.isDone( )); // GuiController -> GuiView : didPOSTPass(bool) + //call initialization functions when setting's ready. + //TODO move the initSettig in the Application POST since it is part of the post. + _settingsError = _settingsWatcher.result(); + //DEBUG qDebug() << " ***** " << sender() << _settingsError; + _post.isDone( ! _settingsError ); + if ( _settingsError ) { + LOG_APPED_PO(QString("Settings read failed")); + onPOSTFail(Gui::GuiAlarmID::ALARM_ID_HD_UI_POST_FAILURE_SETTINGS_BAD); + } else { + _Settings.datetimeFormat(); + } - // HD POST request - postDoneRequest ( ); - versionsRequest (_post.isDone( )); - // UI is done, let's keep in touch - emit didKeepAliveBegin(); + // this singal can be emmited here [ others are postponed to the onTreatmentRangesDone ] + // here we know the CRC was fine with not empty configuration and all files can be read. + emit didSettingsDone( ); // MessageDispatcher -> MessageInterpreter : updateUnhandledMessages } /*! @@ -604,16 +609,27 @@ void ApplicationController::onPOSTCloudSync(bool vPass) { emit didPOSTCloudSync (vPass); - emit didPOSTCloudSyncData("000.000.000.000" /*_post.netCloudSync*/); // not needed and post is not getting it yet.[ApplicationController => DeviceController] + emit didPOSTCloudSyncData("" /*_post.netCloudSync*/); // not needed and post is not getting it yet.[ApplicationController => DeviceController] } /*! * \brief ApplicationController::onPOSTFail - * \details sends the Alarm Trigger message, used when the POST Failed. - * \param vAlarmID + * \details Sends the Alarm Trigger message, if the vSend is true, + * or + * Queues the alarms if vSend is false. + * \param vAlarmID - The alarm ID + * \param vSend - False to queue the ValarmID alarm ID, or True to send the list of the queued alarms. */ -void ApplicationController::onPOSTFail(GuiAlarmID vAlarmID) { - emit didActionTransmit(GuiActionType::ID_AlarmTriggered, {vAlarmID ,0,0,0,0,0,0,0}); +void ApplicationController::onPOSTFail(GuiAlarmID vAlarmID, bool vSend) { + static QVector failList; + if ( vSend ) { + for ( auto alarmID : failList ) { + emit didActionTransmit(Gui::GuiActionType::ID_AlarmTriggered, {alarmID ,0,0,0,0,0,0,0}); + } + } + else { + failList.append(vAlarmID); + } } /*! @@ -642,14 +658,11 @@ /*! * \brief ApplicationController::versionsRequest * \details Sends a version request - * \param vPass - condition to request for version if POST is done */ -void ApplicationController::versionsRequest(bool vPass) { - if (vPass) { - AdjustVersionsRequestData adjustVersionsRequestData; - emit didAdjustment(adjustVersionsRequestData); - LOG_DEBUG("POSTInfReq Sent"); - } +void ApplicationController::versionsRequest() { + AdjustVersionsRequestData adjustVersionsRequestData; + emit didAdjustment(adjustVersionsRequestData); + LOG_DEBUG("POSTVersionReq Sent"); } /*! @@ -671,8 +684,13 @@ * \details It is the slot to handle _DeviceController::didCryptSetupMount signal. * Tels the settings start initate. */ -void ApplicationController::onCryptSetupMount(bool /*vPass*/) +void ApplicationController::onCryptSetupMount(bool vPass) { + //DEBUG qDebug() << " ***** " << Q_FUNC_INFO << vPass; + if ( ! vPass ) { + _post.isDone(vPass); + onPOSTFail(Gui::GuiAlarmID::ALARM_ID_HD_UI_POST_FAILURE_SETTINGS_BAD); + } // if ( vPass ) // it needs more investigation initSettings(); } @@ -683,6 +701,29 @@ */ void ApplicationController::onLogIOFail() { - //DEBUG: qDebug()< GuiView : didPOSTPass(bool) +} + Index: sources/ApplicationController.h =================================================================== diff -u -rcfc0236d4aae3188491f8467df87b961c8069c44 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/ApplicationController.h (.../ApplicationController.h) (revision cfc0236d4aae3188491f8467df87b961c8069c44) +++ sources/ApplicationController.h (.../ApplicationController.h) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -55,7 +55,8 @@ QThread *_thread = nullptr; bool _init = false; - QFutureWatcher _settingsWatcher; + QFutureWatcher _settingsWatcher; + int _settingsError = 0; ApplicationPost _post; // I may need to be put in a concurrent. @@ -81,7 +82,7 @@ void createFakeSeqAtBeginLongMessage(QVariantList &vData, const int vFakeDataLen); void postDoneRequest(); - void versionsRequest(bool vPass); + void versionsRequest(); private slots: // Should be private for thread safety and is connected internally. void onActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG @@ -115,13 +116,15 @@ void onPOSTBluetooth (bool vPass); void onPOSTCloudSync (bool vPass); - void onPOSTFail (Gui::GuiAlarmID vAlarmID); + void onPOSTFail (Gui::GuiAlarmID vAlarmID, bool vSend = false); void onPOSTDone (bool vPass); void onQuitApplication (); void onLogIOFail(); + void onTreatmentRangesDone(bool vPass); + signals: void didPOSTEthernet (bool vPass); void didPOSTWireless (bool vPass); Index: sources/gui/GuiController.cpp =================================================================== diff -u -rb9d5efd980be633f5d0bd92cc76295f3a0669db4 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/gui/GuiController.cpp (.../GuiController.cpp) (revision b9d5efd980be633f5d0bd92cc76295f3a0669db4) +++ sources/gui/GuiController.cpp (.../GuiController.cpp) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -391,3 +391,12 @@ { emit didQuitApplication(); } + +/*! + * \brief GuiController::doTreatmentRangesDone + * \details emit the didTreatmentRangesDone signal to ask ApplicationController to emit alarm that settings are bad + */ +void GuiController::doTreatmentRangesDone(bool vPass) +{ + emit didTreatmentRangesDone(vPass); +} Index: sources/main.h =================================================================== diff -u -rc30ee08fbc73ee5fcd54a7bf0e996eb6a067b7a7 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/main.h (.../main.h) (revision c30ee08fbc73ee5fcd54a7bf0e996eb6a067b7a7) +++ sources/main.h (.../main.h) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -7,7 +7,7 @@ * * \file main.h * \author (last) Behrouz NematiPour - * \date (last) 18-Jul-2023 + * \date (last) 26-Jul-2023 * \author (original) Behrouz NematiPour * \date (original) 28-Oct-2019 * @@ -101,6 +101,7 @@ extern bool gEnableDryDemo ; extern QString gActiveCANBus ; extern bool gEnableManufacturing ; +extern bool gEnableUpdating ; extern bool gUseRootHome ; Index: sources/storage/Logger.h =================================================================== diff -u -rb9d5efd980be633f5d0bd92cc76295f3a0669db4 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/storage/Logger.h (.../Logger.h) (revision b9d5efd980be633f5d0bd92cc76295f3a0669db4) +++ sources/storage/Logger.h (.../Logger.h) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -37,6 +37,7 @@ #define LOG_DEBUG(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogDebug, true ) #define LOG_APPED_UI(vCONTENT) emit Storage::Logger::I().didLog(" ,UI," + vCONTENT, Storage::Logger::LogType::eLogAppED, true ) +#define LOG_APPED_PO(vCONTENT) emit Storage::Logger::I().didLog("POST,UI," + vCONTENT, Storage::Logger::LogType::eLogAppED, true ) #define LOG_APPED_MSG(vID, vTEXT) LOG_APPED(QString("%1,%2").arg(QString("%1").arg(vID,4,16,QLatin1Char('0')).toUpper()).arg(vTEXT)) // forward declarations Index: sources/storage/Settings.cpp =================================================================== diff -u -r689177edf29dee6f10bebfed42f6bbadeb7ce8a8 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/storage/Settings.cpp (.../Settings.cpp) (revision 689177edf29dee6f10bebfed42f6bbadeb7ce8a8) +++ sources/storage/Settings.cpp (.../Settings.cpp) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -52,33 +52,36 @@ /*! * \brief Settings::doRead * \details Reads all the configuration files + * \return non-zero, error value on error, and zero on success. */ int Settings::read() { - int err = Settings::Settings_Error::eError_None; + int err = Settings::Settings_Error::eError_None; QStringList fileFilter = QStringList() << QString("*.%1").arg(_settingsExt); QFileInfoList settingFiles = FileHandler::find (Storage::Settings_Path(), fileFilter); QStringList settingFolders = FileHandler::subFolders(Storage::Settings_Path()); if ( ! settingFolders.count() ) { err = Settings::Settings_Error::eError_No_SettingsFolder; - LOG_DEBUG(errorMessage(err).arg(Storage::Settings_Path())); + LOG_APPED_PO(errorMessage(err).arg(Storage::Settings_Path())); return err; } for ( QString &settingFolder : settingFolders ) { QString folder = settingFolder.prepend(Storage::Settings_Path()); settingFiles += FileHandler::find(folder, fileFilter); } + // DEBUG: // settingFiles = // { // QFileInfo("/home/denali/Projects/application/resources/settings/Confirm/Confirm.conf"), // QFileInfo("/home/denali/Projects/application/resources/settings/Alarms/Alarms.conf") // }; + if ( ! settingFiles.count() ) { err = Settings::Settings_Error::eError_No_SettingsFile; - LOG_DEBUG(errorMessage(err).arg(Storage::Settings_Path())); + LOG_APPED_PO(errorMessage(err).arg(Storage::Settings_Path())); return err; } @@ -87,14 +90,24 @@ if (! isValid(settingFile.absoluteFilePath())) continue; QFile file(settingFile.absoluteFilePath()); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - Detail detail; - detail.content = file.readAll().trimmed(); - if (detail.content.isEmpty()) continue; - detail.location = settingFile.absolutePath() + "/"; - detail.category = QString(detail.location + settingFile.baseName()).remove(Storage::Settings_Path()); - details += detail; + if (! file.open(QIODevice::ReadOnly | QIODevice::Text)) { + err = Settings::Settings_Error::eError_Read; + LOG_APPED_PO(errorMessage(err).arg(Storage::Settings_Path())); + return err; } + + Detail detail; + detail.content = file.readAll().trimmed(); + if (detail.content.isEmpty()) { + //TODO Do not error out for now, the list of the config files which can be empty or not needs to be defined. + // err = Settings::Settings_Error::eError_Empty; + LOG_APPED_PO(errorMessage(Settings::Settings_Error::eError_Empty).arg(settingFile.fileName())); + continue; + } + + detail.location = settingFile.absolutePath() + "/"; + detail.category = QString(detail.location + settingFile.baseName()).remove(Storage::Settings_Path()); + details += detail; } for (const auto &detail : details) { @@ -125,7 +138,7 @@ else if ( line == attribute.arg(_duplicate_key_off ) ) { enableDuplicateKey = false ;} else { - LOG_APPED_UI(( "Unknown '" + line + "' attribute in %1").arg(detail.category)); + LOG_APPED_PO(( "Unknown '" + line + "' attribute in %1").arg(detail.category)); } } Index: sources/storage/Settings.h =================================================================== diff -u -r689177edf29dee6f10bebfed42f6bbadeb7ce8a8 -r9febb7ea48512fb5cee8006a93e7cf030c86815d --- sources/storage/Settings.h (.../Settings.h) (revision 689177edf29dee6f10bebfed42f6bbadeb7ce8a8) +++ sources/storage/Settings.h (.../Settings.h) (revision 9febb7ea48512fb5cee8006a93e7cf030c86815d) @@ -55,11 +55,13 @@ // { Class SettingsError public: enum Settings_Error { - eError_None , + eError_None = 0 , // always has to be 0 eError_POST , eError_PathEmpty , eError_MkDir , eError_Write , + eError_Read , + eError_Empty , eError_Copy , eError_Remove , eError_No_SettingsFolder , @@ -73,6 +75,8 @@ { eError_PathEmpty , "The settings path is empty." }, { eError_MkDir , "The configuration folder '%1' cannot be created." }, { eError_Write , "The settings file %1 can't be written." }, + { eError_Read , "The settings file %1 can't be read." }, + { eError_Empty , "The settings file %1 is empty." }, { eError_Copy , "The configuration folder '%1' cannot be copied." }, { eError_Remove , "The configuration folder '%1' cannot be removed." }, { eError_No_SettingsFolder , "No settings folder in the %1 path found." },