Index: sources/cloudsync/CloudSyncController.cpp =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -113,6 +113,8 @@ this , SLOT( onWatchFileChange (const QString &))); connect(&_DeviceController , SIGNAL(didFactoryReset (bool)), this , SLOT( onFactoryReset (bool))); + connect(&_DeviceController , SIGNAL(didDecommissioning (bool)), + this , SLOT( onDecommissioning (bool))); connect(&_TreatmentLog , SIGNAL(didPendingTxr (const QString &)), this , SLOT( onPendingTxr (const QString &))); connect(this , SIGNAL(didInitComplete ()), @@ -222,7 +224,7 @@ /*! * \brief CloudSyncController::onFactoryReset * \details this slot will be called when the DeviceController is done with the Factory Reset - * to let the UI request CS to do the Factory Reset and clean up all the Tokens. + * to let the UI request CS to do the Factory Reset and clean up all the Logs. * \param vPass - Device controller factory reset was successful. */ void CloudSyncController::onFactoryReset(bool vPass) @@ -233,6 +235,19 @@ } /*! + * \brief CloudSyncController::onDecommissioning + * \details this slot will be called when the DeviceController is done with the Decommissioning + * to let the UI request CS to do the Decommissioning and clean up all the Tokens. + * \param vPass - Device controller Decommissioning was successful. + */ +void CloudSyncController::onDecommissioning(bool vPass) +{ + if ( vPass ) { + csDecommissioning(); + } +} + +/*! * \brief CloudSyncController::onWatchFileChange * \details This slot will be called when the Device Controller identifies any changes in the watched files. * \param vFile - watched file @@ -765,13 +780,23 @@ sendPendingTxr(vFileName); } -// ------------------------------------------------------------------------ TODO: Improve : fucntion description +/*! + * \brief CloudSyncController::onPendingLog + * \details The signal handler to call the function to send the CloudSync a message to upload the pending file. + * \param vFileName - The pending file name + * \param vChecksum - The sha256sum of the file content + */ void CloudSyncController::onPendingLog(const QString &vFileName, const QString vChecksum) { sendPendingLog(vFileName, vChecksum); } -// ------------------------------------------------------------------------ TODO: Improve : fucntion description +/*! + * \brief CloudSyncController::sendPendingLog + * \details The function to send CloudSync a message to uplaod the pending log file. + * \param vFileName - The pending file name + * \param vChecksum - The sha256sum of the file content + */ void CloudSyncController::sendPendingLog(const QString &vFileName, const QString vChecksum) { bool ok = true; Q_UNUSED(ok) @@ -801,8 +826,7 @@ if ( vMessage.params.isEmpty() ) { toLog(eError_LogNameNoParam , {}); ok = false; goto lOut; } mLogName = vMessage.params[0].trimmed(); if ( mLogName.isEmpty() ) { toLog(eError_LogNameEmpty , {}); ok = false; goto lOut; } - //DEBUG - qDebug() << " ---------- " << mLogName; + //DEBUG qDebug() << " ---------- " << mLogName; emit didLogUpload( mLogName ); lOut: @@ -864,26 +888,54 @@ /*! * \brief CloudSyncController::csFactoryReset + * \details This function is requesting CloudSync to remove all the logs + * in the logs folder (/media/sd-card/cloudsync/log/) + * during Factory Reset + * It is a request from UI to CS since UI Linux user (denali) should not have access + * to remove the CloudSync logs. + */ +bool CloudSyncController::csFactoryReset() +{ + + bool ok = true; + return ok; // NOT IMPLEMENTED + + QVariantList args ; + Errors_Enum error = eError_Unknown; + qint32 messageID = UI2CS(static_cast( eMessageID_CSFactoryReset )); + + if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; } + sendUIBuff(makeUIBuff( messageID , { } )); + + return ok; +lErr: + toLog(error, args); + return ok; +} + +/*! + * \brief CloudSyncController::Decommissioning * \details This function is requesting CloudSync to remove all the credentials and configurations * in the settings partition (/var/configurations/CloudSync) * during decommissioning * which then it means the device needs to be re-registered to able to communicate with cloud. * It is a request from UI to CS since UI Linux user (denali) should not have access * to remove the CloudSync credentials. */ -void CloudSyncController::csFactoryReset() +bool CloudSyncController::csDecommissioning() { - bool ok = true; Q_UNUSED(ok) + bool ok = true; QVariantList args ; Errors_Enum error = eError_Unknown; - qint32 messageID = UI2CS(static_cast( eMessageID_CSFactoryReset )); + qint32 messageID = UI2CS(static_cast( eMessageID_CSDecommissioning )); if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; } sendUIBuff(makeUIBuff( messageID , { } )); - return; + return ok; lErr: toLog(error, args); + return ok; } /*! Index: sources/cloudsync/CloudSyncController.h =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/cloudsync/CloudSyncController.h (.../CloudSyncController.h) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/cloudsync/CloudSyncController.h (.../CloudSyncController.h) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -177,10 +177,12 @@ eMessageID_TxReport = 7, // [ UI(1007) -> CS(2007) ] TxReport Notify // Tx Code eMessageID_TxCodeDisplay = 8, // [ CS(2008) -> UI( ) ] Display TxCode Request - // Factory Reset - eMessageID_CSFactoryReset = 9, // [ UI(1009) <-> CS(2009) ] Factory Reset Request + // Decommissioning + eMessageID_CSDecommissioning= 9, // [ UI(1009) <-> CS(2009) ] Decommissioning Request // Log Upload eMessageID_SendLogUpload = 10, // [ UI(1010) <-> CS(2010) ] Log Upload Request/Response + // Factory Reset + eMessageID_CSFactoryReset = 99, // [ UI(1009) <-> CS(2009) ] Factory Reset Request // NOT IMPLEMENTED // // Subject to change so has been commented out for now @@ -228,6 +230,7 @@ void onPOSTCloudSync (bool vPass ); void onCryptSetupMount (bool vPass ); void onFactoryReset (bool vPass ); + void onDecommissioning (bool vPass ); signals: void didInitComplete (); @@ -295,7 +298,8 @@ // Factory Reset - void csFactoryReset (); // eMessageID_FactoryReset + bool csDecommissioning (); // eMessageID_CSDecommissioning + bool csFactoryReset (); // eMessageID_CSFactoryReset bool uiFactoryReset (); // eMessageID_FactoryReset bool sendFactoryReset (); // eMessageID_FactoryReset Index: sources/device/DeviceController.cpp =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -970,44 +970,67 @@ emit didPOSTCloudSyncData (vNetAddress); } -void DeviceController::onLogBackup(const QString &vFileName) +bool DeviceController::logBackup(const QString &vFileName) { + if ( ! gLongLogName ) return false; + + bool ok = true; QFileInfo fileInfo(vFileName); QString filePath(fileInfo.absolutePath()); QString fileBase(fileInfo.baseName()); - // ------------------------------------------------------------------------ TODO: Improve : get pending type extention - QString fileSufx(fileInfo.completeSuffix().prepend("u.")); + QString fileSufx(fileInfo.completeSuffix().prepend(_Logger.logFileNamePendingSubExt())); QString fileDest(QString("%1/%2.%3").arg(filePath, fileBase, fileSufx)); // DEBUG // qDebug() << ""; // qDebug() << vFileName; // qDebug() << fileDest; - QFile::rename(vFileName, fileDest); + ok = QFile::rename(vFileName, fileDest); + return ok; } -void DeviceController::onLogUpload(const QString &vFileName) +void DeviceController::onLogBackup(const QString &vFileName) { + if ( ! gLongLogName ) return; + + bool ok = true; + ok = logBackup( vFileName); + emit didLogBackup(ok, vFileName); +} + +bool DeviceController::logUpload(const QString &vFileName) +{ + if ( ! gLongLogName ) return false; + + bool ok = true; QFileInfo fileInfo(vFileName); - QString filePath(Storage::Log_Folder_Base); + QString filePath; QString fileBase(fileInfo.baseName()); - // ------------------------------------------------------------------------ TODO: Improve : get pending type extention - QString fileSufx(fileInfo.completeSuffix().remove("u.")); - // ------------------------------------------------------------------------ TODO: Improve : get type - if( fileSufx == "log" ) { - filePath += Storage::Log_Folder_Application; - } - // ------------------------------------------------------------------------ TODO: Improve : get type - if( fileSufx == "err" ) { - filePath += Storage::Log_Folder_Service; - } - QString fileDest(QString("%1.%2").arg(fileBase, fileSufx)); + QString ext = _Logger.logFileNamePendingSubExt(); + QString fileSufx(fileInfo.completeSuffix().remove(ext)); + QString fileDest = QString("%1.%2").arg(fileBase, fileSufx); + + Logger::LogType logType = _Logger.logFileLogType(vFileName, filePath); + ok = logType != Logger::eLogNone; + if ( ! ok ) { LOG_APPED_UI(QString("CS Incorrect log upload type [%1]").arg(fileSufx)); goto lOut; } // DEBUG // qDebug() << ""; // qDebug() << vFileName; // qDebug() << fileDest; - QFile::rename(filePath + vFileName, filePath + fileDest); + + ok = QFile::rename(filePath + vFileName, filePath + fileDest); +lOut: + return ok; } +void DeviceController::onLogUpload(const QString &vFileName) +{ + if ( ! gLongLogName ) return; + + bool ok = true; + ok = logUpload( vFileName); + emit didLogUpload(ok, vFileName); +} + /*! * \brief DeviceController::checkConfugurationMountReady * \details Cheks if the system is ready to mount the encrypted partition. @@ -1050,6 +1073,8 @@ */ void DeviceController::findPendingLogs() { + if ( ! gLongLogName ) return; + static QString pendingLog = ""; if( _pendingCounter ) { _pendingCounter -- ; @@ -1061,9 +1086,7 @@ QFileInfoList pendingFiles; QString logLoc = Log_Folder_Base; - // ------------------------------------------------------------------------ TODO: Improve : get pending type extention - QString logExt = "*.u.*"; - + QString logExt = QString("*.%1*").arg(_Logger.logFileNamePendingSubExt()); // "*.u.*"; for( auto logFolder : { Log_Folder_Application, Log_Folder_Service/*, Log_Folder_CloudSync*/ } ) { pendingFiles = Storage::FileHandler::find( logLoc + logFolder, { logExt } ); // look into the list. @@ -1115,7 +1138,7 @@ MDeviceFactoryResetResponse model; model._data.mAccepted = false; // will indirectly set the property factoryResetEnabled model._data.mMessage = tr("Factory Reset started."); - didAttributeResponse(model.data()); + emit didAttributeResponse(model.data()); } /*! @@ -1134,8 +1157,8 @@ else deviceInfo = _processFactoryReset.readAll(); model.fromByteArray( deviceInfo, &vExitCode ); // DEBUG: qDebug() << model._data.mMessage << deviceInfo; - emit didAttributeResponse(model.data()); - emit didFactoryReset(model._data.mAccepted); + emit didAttributeResponse (model.data()); + emit didFactoryReset (model._data.mAccepted); LOG_APPED_UI(model.data().mMessage); } @@ -1166,7 +1189,7 @@ MDeviceDecommissionResponse model; model._data.mAccepted = false; // will indirectly set the property decommissionEnabled model._data.mMessage = tr("Decommissioning started."); - didAttributeResponse(model.data()); + emit didAttributeResponse(model.data()); } /*! @@ -1185,7 +1208,9 @@ else deviceInfo = _processDecommission.readAll(); model.fromByteArray( deviceInfo, &vExitCode ); // DEBUG: qDebug() << model._data.mMessage << deviceInfo; - didAttributeResponse(model.data()); + emit didAttributeResponse (model.data()); + emit didDecommissioning (model._data.mAccepted); + LOG_APPED_UI(model.data().mMessage); } @@ -1227,7 +1252,7 @@ MDeviceUSBMountResponse model; model._data.mAccepted = false; model._data.mMessage = vIsMount ? tr("USB unmount started.") : tr("USB mount started"); - didAttributeResponse(model.data()); + emit didAttributeResponse(model.data()); } /*! @@ -1242,7 +1267,7 @@ if ( vStatus ) vExitCode = Device::DeviceError::eDevice_Scripts_Error_Status; else deviceInfo = _processUSBMount.readAll(); model.fromByteArray( deviceInfo, &vExitCode ); - didAttributeResponse(model.data()); + emit didAttributeResponse(model.data()); // Re-evaluate the USB space available - need to call this here to avoid // visual lag caused by waiting to call this function on the timer timeout Index: sources/device/DeviceController.h =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/device/DeviceController.h (.../DeviceController.h) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/device/DeviceController.h (.../DeviceController.h) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -51,8 +51,9 @@ private slots: void onFinish(int) { killTimer(_pid); + emit _process->finished(-1, QProcess::CrashExit); _process->kill(); - _process = nullptr; + _process->deleteLater(); deleteLater(); } public: @@ -64,10 +65,13 @@ void start() { #ifdef BUILD_FOR_DESKTOP qDebug() << "DeviceController.TimedProcess: " << _timeout << _command << _arguments; -#else + QFileInfo fileInfo(_command); + QString path = fileInfo.absolutePath(); + QString name = "empty.sh"; + _command = QString("%1/%2").arg(path, name); +#endif _pid = startTimer(_timeout); _process->start(_command, _arguments); -#endif } protected: @@ -186,6 +190,9 @@ void findPendingLogs(); + bool logBackup(const QString &vFileName); + bool logUpload(const QString &vFileName); + signals: /*! * \brief didScreenshot @@ -290,21 +297,47 @@ * to notify the ApplicationController to call initSettings */ void didCryptSetupMount ( bool vPass ); + /*! * \brief didFactoryReset - * \details will be emitted when the factory reset is done, - * to notify the CloudSyncController to do the FactoryReset/TokenRemoval. + * \details will be emitted when the Factory Reset is done, + * to notify the CloudSyncController to do the Factory Reset/Logs Removal. * \param vPass */ void didFactoryReset ( bool vPass ); /*! + * \brief didDecommissioning + * \details will be emitted when the Decommissioning is done, + * to notify the CloudSyncController to do the Decommissioning/TokenRemoval. + * \param vPass + */ + void didDecommissioning ( bool vPass ); + + /*! * \brief didPendingLog * \details will be emitted when a log file is pending to be uploaded. * \param vFileName - the pending log file name */ void didPendingLog (const QString &vFileName, const QString vChecksum ); + /*! + * \brief logBackup + * \details notification of the log back up complete (either case of pass or fail) + * \param vFileName - file name to backup + * \param vPass - false if the backup failed. + * \return void + */ + void didLogBackup ( bool vPass, const QString &vFileName ); + + /*! + * \brief didLogUpload + * \details notification of pending log upload file rename complete (rename and remove the 'u.' (pending sub-ext)) + * \param vPass - true if the pending log file name rename was successful. + * \param vFileName - the pending log file name (meaning it includes 'u.' ) + */ + void didLogUpload ( bool vPass, const QString &vFileName ); + private: // ----- USB void usbCheck (); Index: sources/storage/Logger.cpp =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/storage/Logger.cpp (.../Logger.cpp) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/storage/Logger.cpp (.../Logger.cpp) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -40,7 +40,11 @@ * \param parent - QObject parent owner object. * Qt handles the children destruction by their parent objects life-cycle. */ -Logger::Logger(QObject *parent) : QObject(parent) {} +Logger::Logger(QObject *parent) : QObject(parent) { + if ( ! gLongLogName ) { + _fileDateFormat = "yyyy_MM_dd"; // date used in the file name + } +} /*! * \brief Logger::init @@ -338,15 +342,22 @@ _logFileNameTime = QDateTime::currentDateTime().time().toString(_fileTimeFormat); } - QString fileName = _logFileNameDate - + _fileSeparator + _logFileNameTime - + _fileSeparator + _logFileNameHDSN - + _fileSeparator + _logFileNameMode - ; + QString fileName; + if ( ! gLongLogName ) { + fileName = _logFileNameDate + + _fileSeparator + "denali"; + } + else { + fileName = _logFileNameDate + + _fileSeparator + _logFileNameTime + + _fileSeparator + _logFileNameHDSN + + _fileSeparator + _logFileNameMode + ; + } // case LogType::eLogTrtmt: // this type of log will never happen here. Only put here to make sure it is intentional. switch (vLogType) { case LogType::eLogAppED: { - // ------------------------------------------------------------------------ TODO: Improve : fucntion declaration + // ------------------------------------------------------------------------ TODO: Improve : function declaration fileName += _logFileNameExt[vLogType]; static QString oFileName; if( oFileName != fileName ) { @@ -361,7 +372,7 @@ } break; case LogType::eLogDebug: { - // ------------------------------------------------------------------------ TODO: Improve : fucntion declaration + // ------------------------------------------------------------------------ TODO: Improve : function declaration fileName += _logFileNameExt[vLogType]; static QString oFileName; if( oFileName != fileName ) { @@ -537,7 +548,7 @@ quint32 opMode = vData[0].toUInt(&ok); if ( ! ok ) return; quint32 subMode = vData[1].toUInt(&ok); if ( ! ok ) return; QString mode; - if ( subMode >= GuiHDStandbyStates::STANDBY_WAIT_FOR_DISINFECT_STATE ) { + if ( opMode == GuiHDOpModes::MODE_STAN && subMode >= GuiHDStandbyStates::STANDBY_WAIT_FOR_DISINFECT_STATE ) { mode = "Disinfect"; if( _logFileNameMode != mode ) { _logFileNameMode = mode; Index: sources/storage/Logger.h =================================================================== diff -u -re38423dd3840e625ed0728d9b0fb3f9eb9292500 -ra527408b1941641fe0f60e866d0c122fdf519551 --- sources/storage/Logger.h (.../Logger.h) (revision e38423dd3840e625ed0728d9b0fb3f9eb9292500) +++ sources/storage/Logger.h (.../Logger.h) (revision a527408b1941641fe0f60e866d0c122fdf519551) @@ -112,7 +112,7 @@ // The Mode is the device main states comming from HD_OpMode // this is not exactly the HD_OpModes and will be interpreted in desired cycles. // At the moment we decided to have Standby, Treatment, Disinfection, and I am adding Initial as well. - // Initially + // NoRunning // Treatment // Disinfect // DisinfectHeat // later: the UI message needs to get updated and not using SubMode @@ -121,27 +121,31 @@ // DisinfectFlsh // later: the UI message needs to get updated and not using SubMode // "Disinfect" // "Treatment" - const char *_logFileNameMode_init = "NotRunnig"; + const char *_logFileNameMode_init = "NoRunning"; QString _logFileNameMode = "" ; QString _logFileNameDate = "" ; QString _logFileNameTime = "" ; - QHash _logPathNames; - const QHash _logBasePathNames { + typedef QHash TLogData; + typedef QHash TLogMaxUse; + + TLogData _logPathNames; + const TLogData _logBasePathNames { { LogType::eLogAppED, Storage::Log_Folder_Application}, { LogType::eLogDebug, Storage::Log_Folder_Service }, { LogType::eLogCloud, Storage::Log_Folder_CloudSync }, { LogType::eLogTrtmt, Storage::Txr_Folder_Treatment }, }; - const QHash _logNames { // Will be used for the logging in the file + const TLogData _logNames { // Will be used for the logging in the file { LogType::eLogAppED, "Log" }, { LogType::eLogDebug, "Service" }, { LogType::eLogCloud, "Cloud" }, { LogType::eLogTrtmt, "Treatment" }, }; - const QHash _logFileNameExt { + const char * _logFileNamePendingSubExt = "u."; + const TLogData _logFileNameExt { { LogType::eLogAppED, ".log" }, // Application log { LogType::eLogDebug, ".err" }, // Application error { LogType::eLogCloud, ".log" }, // CloudSync debug @@ -151,7 +155,7 @@ // !!!!!!!!!! IMPORTANT !!!!!!!!!! // be careful with these percentages // please refer to the Storage namespace. - const QHash _logTypeMaxUsageLimit { + const TLogMaxUse _logTypeMaxUsageLimit { { LogType::eLogAppED, Storage::Log_Max_Allowable_AppED_Space_Percent }, { LogType::eLogDebug, Storage::Log_Max_Allowable_Debug_Space_Percent }, { LogType::eLogCloud, Storage::Log_Max_Allowable_Cloud_Space_Percent }, @@ -179,6 +183,49 @@ bool _init = false; public: + QString logFileNamePendingSubExt() { + return _logFileNamePendingSubExt; + } + + QString logFileNameExt ( LogType vLogType ) { + return _logFileNameExt[vLogType]; + } + + QString logPathName(LogType vLogType) { + return _logPathNames[vLogType]; + } + + /*! + * \brief logFileNameExt_AD + * \details Finds the type of the log by log file extention. + * \note Since the log file ext of the cloud and UI are the same, this finction will ignore the eLogCloud and will return eLogAppED type instead. + * \param vLogExt - the log file extention. + * \return + */ + LogType logFileNameExt_AD ( const QString &vLogExt ) { + if ( _logFileNameExt.values().contains(vLogExt) ) { + LogType logType = _logFileNameExt.key(vLogExt); + if ( logType == eLogCloud) logType = eLogAppED; + return logType; + } + return eLogNone; + } + + LogType logFileLogType (const QString &vFileName, QString &vFilePath) { + QFileInfo fileInfo(vFileName); + QString ext = fileInfo.suffix(); + LogType logType = logFileNameExt_AD("." + ext); + QString logFilePath; + if ( logType != eLogNone ) { + logFilePath = Log_Folder_Base + _logBasePathNames[logType]; + } + if ( fileInfo.exists(logFilePath + vFileName) ) { + vFilePath = logFilePath; + return logType; + } + return eLogNone; + } +public: void enableConsoleOut(bool vEnabled); void postInit();