#include "worker.h" #include "update.h" #include <QCoreApplication> #include <QApplication> #include <QDebug> #include <QTimer> #include <QFileInfo> #include <QDir> #include <QDirIterator> #include <QThread> #include <QRegularExpression> #include <QDateTime> #include <QString> #include "message_handler.h" #include "plugins/interfaces.h" #include "ismas/ismas_client.h" #include "apism/apism_client.h" int Worker::read1stLineOfFile(QString fileName) { QFile f(fileName); if (f.exists()) { if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&f); in.setCodec("UTF-8"); while(!in.atEnd()) { return in.readLine().toInt(); } } } return -1; } Worker::Worker(hwinf *hw, int customerNr, int machineNr, int zoneNr, QString branchName, QString workingDirectory, bool maintenanceMode, bool dryRun, QObject *parent, char const *serialInterface, char const *baudrate) : m_hw(hw) , m_workerThread("workerThread") , m_apismClient(0, 0, 0, this) // TODO , m_customerNr(customerNr) , m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0')) , m_machineNr(machineNr) , m_zoneNr(zoneNr) , m_workingDirectory(workingDirectory) , m_branchName(branchName) , m_customerRepositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr)) , m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr)) , m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this) , m_maintenanceMode(maintenanceMode) , m_osVersion(getOsVersion()) , m_atbqtVersion(getATBQTVersion()) , m_cpuSerial(getCPUSerial()) , m_raucVersion(getRaucVersion()) , m_opkgVersion(getOpkgVersion()) , m_pluginVersionATBDeciceController(getPluginVersion("/opt/app/ATBAPP/plugins/libATBDeviceControllerPlugin.so")) , m_pluginVersionIngenicoISelf(getPluginVersion("/opt/app/ATBAPP/plugins/libIngenicoISelf_CCPlugin.so")) , m_pluginVersionMobilisisCalc(getPluginVersion("/opt/app/ATBAPP/plugins/libMOBILISIS_CalculatePricePlugin.so")) , m_pluginVersionMobilisisCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libMOBILISIS_CalculatePricePlugin_ConfigUi.so")) , m_pluginVersionPrmCalc(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin.so")) , m_pluginVersionPrmCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin_ConfigUi.so")) , m_pluginVersionTcpZvt(getPluginVersion("/opt/app/ATBAPP/plugins/libTCP_ZVT_CCPlugin.so")) , m_ismasUpdateRequests(ISMAS_UPDATE_REQUESTS) , m_waitForNewUpdates(this) { QDir::setCurrent(m_workingDirectory); qInfo() << "CURRENT TIME ..............." << QDateTime::currentDateTime().toString(Qt::ISODate); qInfo() << "OS VERSION ................." << m_osVersion; qInfo() << "ATBQT VERSION .............." << m_atbqtVersion; qInfo() << "CPU SERIAL ................." << m_cpuSerial; qInfo() << "CUSTOMER_NR ................" << m_customerNr; qInfo() << "CUSTOMER_NR_STR ............" << m_customerNrStr; qInfo() << "CUSTOMER_REPOSITORY_PATH ..." << m_customerRepositoryPath; qInfo() << "CUSTOMER_REPOSITORY ........" << m_customerRepository; qInfo() << "MACHINE_NR ................." << m_machineNr; qInfo() << "ZONE_NR ...................." << m_zoneNr; qInfo() << "BRANCH_NAME ................" << m_branchName; qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory; //QProcess p; //p.start("/bin/systemctl", {"restart", "apism"}); //if (!p.waitForStarted(5000) || !p.waitForFinished(5000)) { // qCritical() << "APISM-RESTART-FAILURE"; // return; //} this->moveToThread(&m_workerThread); m_workerThread.start(); int cnt = 0; while (!m_workerThread.isRunning()) { if (++cnt > 5) { qCritical() << "starting worker thread FAILED"; return; } QThread::sleep(1); } connect(&m_apismClient, SIGNAL(ismasResponseAvailable(QJsonObject)), this, SLOT(onIsmasResponseReceived(QJsonObject))); connect(this, SIGNAL(summarizeRepositoryStatus()), this, SLOT(onSummarizeRepositoryStatus()), Qt::QueuedConnection); connect(this, SIGNAL(sendCmdSendVersionToIsmas()), this, SLOT(onSendCmdSendVersionToIsmas()), Qt::QueuedConnection); connect(this, SIGNAL(summarizeUpload(QStringList)), this, SLOT(onSummarizeUpload(QStringList)), Qt::QueuedConnection); connect(this, SIGNAL(handleChangedFiles(QStringList)), this, SLOT(onHandleChangedFiles(QStringList)), Qt::QueuedConnection); connect(this, SIGNAL(finishUpdateProcess(bool)), this, SLOT(onFinishUpdateProcess(bool)), Qt::QueuedConnection); connect(this, SIGNAL(terminateUpdateProcess()), this, SLOT(onTerminateUpdateProcess()), Qt::QueuedConnection); connect(&m_emergencyTimer, SIGNAL(timeout()), this, SLOT(onTerminateUpdateProcess()), Qt::QueuedConnection); m_emergencyTimer.setSingleShot(true); m_emergencyTimer.start(1000 * 60 * 10); QDir customerRepository(m_customerRepository); if (!customerRepository.exists()) { if (m_gc.gitCloneAndCheckoutBranch()) { // do nothing else, not even executing opkg-commands emit this->finishUpdateProcess(false); } } else { m_update = new Update(m_hw, m_customerRepository, m_customerNrStr, m_branchName, m_workingDirectory, dryRun, parent, serialInterface, baudrate); connect(&m_startUpdateProcess, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection); m_startUpdateProcess.setSingleShot(true); m_startUpdateProcess.start(1000); connect(&m_waitForNewUpdates, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection); m_waitForNewUpdates.setSingleShot(false); } } Worker::~Worker() { int cnt = 0; m_workerThread.quit(); while (!m_workerThread.isFinished()) { if (!m_workerThread.wait(1000)) { if (++cnt > 5) { qCritical() << "stopping worker thread FAILED"; return; } } } if (m_update) { delete m_update; } } QString Worker::getOsVersion() const { QString const cmd = QString("echo -n $(cat /etc/os-release | head -n 1 | cut -d'\"' -f2 | tr -d '\"')"); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QString Worker::getATBQTVersion() const { QString const cmd = QString("echo -n $(/opt/app/ATBAPP/ATBQT -v | head -n 2 | cut -d':' -f2)"); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QString Worker::getCPUSerial() const { QString const cmd = QString("echo -n $(cat /proc/cpuinfo | grep -i Serial | cut -d':' -f2)"); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QString Worker::getRaucVersion() const { QString const cmd = QString("echo -n $(rauc --version)"); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QString Worker::getOpkgVersion() const { QString const cmd = QString("echo -n $(opkg --version)"); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QString Worker::getPluginVersion(QString const &pluginFileName) const { QString const cmd = QString("echo -n $(strings %1 | grep \\\"Version\\\" | cut -d':' -f2 | tr -d '\"' | tr -d ',')").arg(pluginFileName); Command c("bash"); if (c.execute(m_workingDirectory, QStringList() << "-c" << cmd)) { return c.getCommandResult(); } return "N/A"; } QStringList Worker::getDCVersion() const { QStringList lst = (QStringList() << "N/A" << "N/A"); if (m_hw) { m_hw->dc_autoRequest(true); // turn auto-request setting on QByteArray const cmp(8, char(0)); QByteArray hw(""), sw(""); for (int i=0; i<5; ++i) { hw = m_hw->dc_getHWversion().toUtf8(); sw = m_hw->dc_getSWversion().toUtf8(); if (!hw.startsWith(cmp)) { lst.clear(); qInfo() << hw << sw; lst << hw << sw; break; } QThread::sleep(1); } } return lst; } qint64 Worker::getFileSize(QString const &fileName) const { // fileName has to be an absolute path QFileInfo fInfo(fileName); return fInfo.exists() ? fInfo.size() : -1; } void Worker::onHandleChangedFiles(QStringList changedFiles) { QString opkg_commands; static const QRegularExpression re("^.*opkg_commands\\s*$"); static const QRegularExpression comment("^\\s*#.*$"); int idx = changedFiles.indexOf(re); if (idx != -1) { opkg_commands = changedFiles.takeAt(idx); qInfo() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMANDS, QString("EXEC OPKG-COMMANDS FOR ") + opkg_commands); if (QDir::setCurrent(m_customerRepository)) { QFile f(opkg_commands); if (f.exists()) { if (f.open(QIODevice::ReadOnly)) { QTextStream in(&f); while (!in.atEnd()) { QString line = in.readLine(); if (line.indexOf(comment, 0) == -1) { // found opkg command QString opkgCommand = line.trimmed(); executeOpkgCommand(opkgCommand); } } f.close(); qInfo() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS, QString("EXECUTING OPKG-COMMANDS OK")); } } } } if (m_update->doUpdate(changedFiles)) { // first update the hardware // then sync the file-system if (QDir(m_customerRepository).exists()) { if (QDir::setCurrent(m_customerRepository)) { QString const params("--recursive " "--progress " "--checksum " "--exclude=.* " "--include=*.bin " "--include=*.json " "--include=opkg_commands " "--include=*.ini"); QStringList cmds; cmds << QString("rsync ") + params.simplified() + " etc/ /etc"; cmds << QString("rsync ") + params.simplified() + " opt/ /opt"; QString cmd; bool error = false; foreach (cmd, cmds) { if (!error) { Command c("bash"); qInfo() << "EXCUTING CMD..." << cmd; if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) { qDebug() << c.getCommandResult(); } else { qCritical() << "CMD" << cmd << "FAILED"; error = true; } } } if (!error) { emit this->finishUpdateProcess(true); return; } } } } onTerminateUpdateProcess(); } void Worker::onSummarizeUpload(QStringList changedFiles) { QDateTime const c = QDateTime::currentDateTime(); QDate const d = c.date(); QTime const t = c.time(); QString uploadHistoryFile = QString("upload_history_%1%2%3T%4%5%6.txt") .arg(d.year()).arg(d.month()).arg(d.day()) .arg(t.hour()).arg(t.minute()).arg(t.second()); QFile f(uploadHistoryFile); if (f.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&f); QString fName; foreach (fName, changedFiles) { QString lastCommit = m_gc.gitLastCommit(fName); out << fName << ":" << lastCommit << "\n"; } } else { // TODO: error an ISMAS } } void Worker::onSummarizeRepositoryStatus() { // TODO QString dir("/opt/app/tools/atbupdate/customer_999"); QDirIterator it(dir, QStringList() << "*.jpg", QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { qDebug() << it.next(); if (m_gc.gitIsFileTracked(it.next())) { QString lastCommit = m_gc.gitLastCommit(it.next()); } } /* QString repoStatusHistoryFile = QString("repo_status_history_%1%2%3T%4%5%6.txt") .arg(d.year()).arg(d.month()).arg(d.day()) .arg(t.hour()).arg(t.minute()).arg(t.second()); if (f.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&f); QString fName; foreach (fName, changedFiles) { QString lastCommit = m_gc.gitLastCommit(fName); out << fName << ":" << lastCommit << "\n"; } } else { // TODO: error an ISMAS } */ } void Worker::executeOpkgCommand(QString opkgCommand) { Command c(opkgCommand); if (c.execute(m_workingDirectory)) { QString const r = c.getCommandResult(); qInfo() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS, QString("EXECUTE OPKG COMMAND %1 OK: %2") .arg(opkgCommand) .arg(c.getCommandResult())); } else { qCritical() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE, QString("EXECUTE OPKG COMMAND %1 FAILED") .arg(opkgCommand)); onTerminateUpdateProcess(); return; } } // sollte ParameterResponse heissen void Worker::onIsmasResponseReceived(QJsonObject ismasResponse) { qInfo() << "IN ON_ISMAS_RESPONSE_RECEIVED" << QThread::currentThread()->objectName(); if (!ismasResponse.isEmpty()) { QStringList const keys = ismasResponse.keys(); qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED, QString("RECEIVED JSON WITH KEYS: ") + keys.join(",")); static QRegularExpression re("^REQ_ISMASPARAMETER.*"); if(keys.indexOf(re) >= 0) { m_waitForNewUpdates.stop(); // stop asking ISMAS for updates // sanity check: cust_nr and machine_nr of PSA correct ? if (keys.contains("Dev_ID", Qt::CaseInsensitive)) { QJsonObject const devId = ismasResponse["Dev_ID"].toObject(); QStringList const keys = devId.keys(); if (keys.contains("Custom_ID") && keys.contains("Device_ID")) { QJsonValue const c = devId.value("Custom_ID"); QJsonValue const m = devId.value("Device_ID"); int customerNr = c.toInt(-1); int machineNr = m.toInt(-1); if (customerNr != m_customerNr) { m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE; m_statusDescription = QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)") .arg(customerNr).arg(m_customerNr); return; } if (machineNr != m_machineNr) { m_statusDescription = QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)") .arg(machineNr).arg(m_machineNr); m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE; return; } } } // TODO: check if zone_nr is correct if (keys.contains("Fileupload", Qt::CaseInsensitive)) { QJsonObject fileUpload = ismasResponse["Fileupload"].toObject(); QJsonValue v = fileUpload.value("TRG"); if (!v.isNull() && !v.isUndefined()) { QString const s = v.toString(""); if (s == "WAIT") { m_ismasUpdateRequests = ISMAS_UPDATE_REQUESTS; qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS, "DETECTED AVAILABLE ISMAS-DOWNLOAD"); QString const &data = m_ismasClient.updateOfPSAActivated(); m_apismClient.onSendCmdEventToIsmas(data); emit m_gc.ismasUpdatesAvailable(); } else { // TODO: enorm wichtig qCritical() << "DID NOT RECEIVE 'WAIT' BUT" << s; onTerminateUpdateProcess(); } } } else { m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE; m_statusDescription = "NO FILEUPLOAD KEY AVAILABLE"; return; } } } else { m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE; m_statusDescription = "NO ISMAS RESPONSE AVAILABLE (EMPTY)"; } } void Worker::onFinishUpdateProcess(bool changes) { Q_UNUSED(changes); qInfo() << "ON FINISH UPDATE PROCESS" << QThread::currentThread()->objectName(); // m_emergencyTimer.stop(); onSendCmdSendVersionToIsmas(); // final message to ISMAS m_workerThread.quit(); QApplication::quit(); exit(0); } void Worker::onTerminateUpdateProcess() { qCritical() << "ON TERMINATE UPDATE PROCESS"; onSendCmdSendVersionToIsmas(); // final message to ISMAS m_workerThread.quit(); QApplication::quit(); exit(-1); } void Worker::onSendCmdSendVersionToIsmas() { QStringList const dcVersion = getDCVersion(); QString const deviceControllerVersionHW = dcVersion.first(); QString const deviceControllerVersionSW = dcVersion.last(); qInfo() << "CURRENT DC-HW-VERSION: " << deviceControllerVersionHW; qInfo() << "CURRENT DC-SW-VERSION: " << deviceControllerVersionSW; QString const deviceControllerGitBlob = "N/A"; QString const deviceControllerGitLastCommit = "N/A"; PSAInstalled psaInstalled; QString printSysDir("/etc/psa_config"); QString tariffSysDir("/etc/psa_tariff"); QString absPathName; if (m_zoneNr != 0) { QString const &n = QString("%1").arg(m_zoneNr).rightJustified(2, '0'); psaInstalled.tariff.name = QString("tariff%1.json").arg(n); absPathName = QDir::cleanPath(tariffSysDir + QDir::separator() + psaInstalled.tariff.name); psaInstalled.tariff.blob = m_gc.gitBlob(absPathName); psaInstalled.tariff.size = getFileSize(absPathName); psaInstalled.tariff.zone = m_zoneNr; } psaInstalled.tariff.project = "Szeged"; psaInstalled.tariff.info = "N/A"; psaInstalled.tariff.loadTime = "N/A"; // QDateTime::currentDateTime().toString(Qt::ISODateWithMs); psaInstalled.tariff.version = "N/A"; psaInstalled.hw.linuxVersion = m_osVersion; psaInstalled.hw.cpuSerial = m_cpuSerial; psaInstalled.dc.versionHW = deviceControllerVersionHW; psaInstalled.dc.versionSW = deviceControllerVersionSW; psaInstalled.dc.gitBlob = "N/A"; psaInstalled.dc.gitLastCommit = "N/A"; psaInstalled.dc.size = -1; psaInstalled.sw.raucVersion = m_raucVersion; psaInstalled.sw.opkgVersion = m_opkgVersion; psaInstalled.sw.atbQTVersion = m_atbqtVersion; psaInstalled.pluginVersion.deviceController = m_pluginVersionATBDeciceController; psaInstalled.pluginVersion.ingenicoISelfCC = m_pluginVersionIngenicoISelf; psaInstalled.pluginVersion.mobilisisCalculatePrice = m_pluginVersionMobilisisCalc; psaInstalled.pluginVersion.mobilisisCalculatePriceConfigUi = m_pluginVersionMobilisisCalcConfig; psaInstalled.pluginVersion.prmCalculatePrice = m_pluginVersionPrmCalc; psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig; psaInstalled.pluginVersion.tcpZVT = m_pluginVersionTcpZvt; psaInstalled.cash.name = "DC2C_cash.json"; absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name); psaInstalled.cash.blob = m_gc.gitBlob(absPathName); psaInstalled.cash.size = getFileSize(absPathName); psaInstalled.conf.name = "DC2C_conf.json"; absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name); psaInstalled.conf.blob = m_gc.gitBlob(absPathName); psaInstalled.conf.size = getFileSize(absPathName); psaInstalled.device.name = "DC2C_device.json"; absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name); psaInstalled.device.blob = m_gc.gitBlob(absPathName); psaInstalled.device.size = getFileSize(absPathName); for (int i=0; i < 32; ++i) { QString const &n = QString("%1").arg(i+1).rightJustified(2, '0'); psaInstalled.print[i].name = QString("DC2C_print%1.json").arg(n); absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name); psaInstalled.print[i].blob = m_gc.gitBlob(absPathName); psaInstalled.print[i].size = getFileSize(absPathName); } QString data = m_ismasClient.updateOfPSASendVersion(psaInstalled); // printf("data=%s\n", data.toStdString().c_str()); m_apismClient.onSendCmdSendVersionToIsmas(data); } void Worker::askIsmasForNewData() { if (m_maintenanceMode) { m_updateStatus = UPDATE_STATUS::ISMAS_EMULATE_DATA_AVAILABLE; QString data = m_ismasClient.setUpdatesAvailable(); m_apismClient.emulateUpdatesAvailable(data); } //m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING; //m_statusDescription = "Ask ISMAS IF NEW DATA AVAILABLE"; qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING, QString("ASK ISMAS IF NEW DATA AVAILABLE") + QString(" (%1)").arg(m_ismasUpdateRequests)); m_apismClient.requestAvailableIsmasUpdates(); if (--m_ismasUpdateRequests > 0) { // if the timer is already running, it will be stopped and restarted. m_waitForNewUpdates.start(10000); m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING; } else { m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_TIMEOUT; onTerminateUpdateProcess(); } } /************************************************************************************************ * operators */ QDebug operator<< (QDebug debug, UpdateStatus status) { switch(status.m_updateStatus) { case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: debug << QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: ") << status.m_statusDescription; break; case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: debug << QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: ") << status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: ") << status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: ") << status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS: debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS: ") << status.m_statusDescription; break; case UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: debug << QString("UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: ") << status.m_statusDescription; break; case UPDATE_STATUS::GIT_PULL_UPDATES_SUCCESS: debug << QString("UPDATE_STATUS::GIT_PULL_UPDATES_REQUEST: ") << status.m_statusDescription; break; case UPDATE_STATUS::GIT_PULL_UPDATES_FAILURE: debug << QString("UPDATE_STATUS::GIT_PULL_UPDATES_FAILURE: ") << status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMANDS: debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: ") << status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS: debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS: ") << status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS: debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS: ") << status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE: debug << QString("UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE: ") << status.m_statusDescription; break; default:; } return debug; } QString& operator<< (QString& str, UpdateStatus status) { switch(status.m_updateStatus) { case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: str = QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: "); str += status.m_statusDescription; break; case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: str = QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: "); str += status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE: "); str += status.m_statusDescription; break; case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS: str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::GIT_PULL_UPDATES_SUCCESS: str = QString("UPDATE_STATUS::GIT_PULL_UPDATES_SUCCESS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::GIT_PULL_UPDATES_FAILURE: str = QString("UPDATE_STATUS::GIT_PULL_UPDATES_FAILURE: "); str += status.m_statusDescription; break; case UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: str = QString("UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED: "); str += status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMANDS: str = QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS: str = QString("UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS: str = QString("UPDATE_STATUS::EXEC_OPKG_COMMAND_SUCCESS: "); str += status.m_statusDescription; break; case UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE: str = QString("UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE: "); str += status.m_statusDescription; break; default:; } return str; }