Index: sources/device/DeviceController.cpp =================================================================== diff -u -r1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459 -r74999b64a6850dd7622d03937bc8c8a8e0ae421e --- sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 1bf8c894c5cc5ea6d62af0662fcf5a18e1a06459) +++ sources/device/DeviceController.cpp (.../DeviceController.cpp) (revision 74999b64a6850dd7622d03937bc8c8a8e0ae421e) @@ -1,13 +1,13 @@ /*! * - * Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. + * Copyright (c) 2021-2024 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 DeviceController.cpp - * \author (last) Behrouz NematiPour - * \date (last) 10-Sep-2023 + * \author (last) Dara Navaei + * \date (last) 07-Feb-2024 * \author (original) Behrouz NematiPour * \date (original) 03-Jun-2021 * @@ -27,6 +27,7 @@ #include "Threads.h" #include "StorageGlobals.h" #include "Logger.h" +#include "CloudSyncController.h" #include "ApplicationController.h" #include "FileHandler.h" #include "DeviceModels.h" @@ -119,6 +120,11 @@ connect(&_ApplicationController , SIGNAL(didPOSTCloudSyncData (const QString &)), this , SLOT( onPOSTCloudSyncData (const QString &))); + connect(&_Logger , SIGNAL(didLogBackup (const QString &)), + this , SLOT( onLogBackup (const QString &))); + connect(&_CloudSyncController , SIGNAL(didLogUpload (const QString &)), + this , SLOT( onLogUpload (const QString &))); + DEVICE_DEV_INIT_CONNECTIONS_LIST connect(this, SIGNAL(didEventThreadChange()), @@ -243,6 +249,7 @@ // logs and need a separate disk space usage check settingsPartitionSpaceCheck(); #endif + findPendingLogs(); } /*! @@ -283,7 +290,7 @@ qint64 mCTotal = 0; bool isMounted = FileHandler::isMounted(Storage::SDCard_Base_Path_Name); - QString pathToCheckSpace = isMounted ? Storage::SDCard_Base_Path_Name : Storage::Standard_tmp; + QString pathToCheckSpace = isMounted ? Storage::SDCard_Base_Path_Name : gStandard_tmp; mCIsReady = driveSpaceCheck(pathToCheckSpace, mCTotal, mCAvailable, &mCIsReadOnly); //DEBUG: qDebug()<< "Checking space for path of : " << pathToCheckSpace << " mCTotal " << mCTotal << " available " << mCAvailable; @@ -558,7 +565,7 @@ } // ----- run the process - int timeout_ms = 1000; + int timeout_ms = 10000; QStringList params; params << QString::number(_deviceBrightnessRequest._data.mBrightness_val); TimedProcess *timedProcess = new TimedProcess(&_processBrightness, script, timeout_ms, params); @@ -625,9 +632,10 @@ } // ----- run the process + int timeout_ms = 10000; QStringList params; if ( ! _deviceRootSSHAccessRequest._data.mIsGet ) params << FSN(_deviceRootSSHAccessRequest._data.mRootSSHAccess); - TimedProcess *timedProcess = new TimedProcess(&_processRootSSHAccess, script, 1000, params); + TimedProcess *timedProcess = new TimedProcess(&_processRootSSHAccess, script, timeout_ms, params); timedProcess->start(); } @@ -789,7 +797,8 @@ } // ----- run the process - TimedProcess *timedProcess = new TimedProcess(&_processBluetoothPairedReset, script, 2000); + int timeout_ms = 10000; + TimedProcess *timedProcess = new TimedProcess(&_processBluetoothPairedReset, script, timeout_ms); timedProcess->start(); } @@ -820,7 +829,8 @@ } // ----- run the process - TimedProcess *timedProcess = new TimedProcess(&_processBluetoothPairedQuery, script, 1000); + int timeout_ms = 10000; + TimedProcess *timedProcess = new TimedProcess(&_processBluetoothPairedQuery, script, timeout_ms); timedProcess->start(); } @@ -963,6 +973,67 @@ emit didPOSTCloudSyncData (vNetAddress); } +bool DeviceController::logBackup(const QString &vFileName) +{ + if ( ! gLongLogName ) return false; + + bool ok = true; + QFileInfo fileInfo(vFileName); + QString filePath(fileInfo.absolutePath()); + QString fileBase(fileInfo.baseName()); + QString fileSufx(fileInfo.completeSuffix().prepend(_Logger.logFileNamePendingSubExt())); + QString fileDest(QString("%1/%2.%3").arg(filePath, fileBase, fileSufx)); + // DEBUG + // qDebug() << ""; + // qDebug() << vFileName; + // qDebug() << fileDest; + ok = QFile::rename(vFileName, fileDest); + return ok; +} + +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; + QString fileBase(fileInfo.baseName()); + 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; + + 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. @@ -997,6 +1068,54 @@ // and take care of the security flag in the Storage class. } +/*! + * \brief DeviceController::findPendingLogs + * \details this function counts downs for the _pendingInterval + * when the _pendingCounter reaches 0 will search for the files + * and if there is any will get the recent file in the list + */ +void DeviceController::findPendingLogs() +{ + if ( ! gLongLogName ) return; + + static QString pendingLog = ""; + if( _pendingCounter ) { + _pendingCounter -- ; + return; + } + else { + _pendingCounter = _pendingInterval; // every minute + } + + QFileInfoList pendingFiles; + QString logLoc = Log_Folder_Base; + 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. + // if there are pending files, + // send a request only for the top on the list + /// Note I thought it makes sense to send the oldest on the application and service logs + /// but there some conversation about the situation if something happens on the device, + /// and it would be a critical situation to get the recent/top log and won't wait for the old ones to upload. + // * When gets uploaded, moves from pending then next one comes to top + // the process repeats until there is no file in pending + if ( pendingFiles.count() ) { + // the most recent/first Tx file, to first ask for the current treatment which has just saved as pending on screen + _pendingLog = pendingFiles.first().absoluteFilePath(); + QString message = pendingLog; + LOG_DEBUG(message); + emit didPendingLog( _pendingLog, FileHandler::sha256sum( _pendingLog ) ); + // when a pending file found in the first log folder stop + // until there is none in first one (log) + // then continue to the next log folder (service) ... + goto lOut; + } + } +lOut: + return; +} + ///////////////////////////////////////////// DeviceFactoryReset void DeviceController::onAttributeRequest(const DeviceFactoryResetRequestData &vData) { @@ -1022,7 +1141,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()); } /*! @@ -1041,8 +1160,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); } @@ -1073,7 +1192,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()); } /*! @@ -1092,7 +1211,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); } @@ -1134,7 +1255,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()); } /*! @@ -1149,7 +1270,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