UpdatePTUDevCtrl/worker.cpp

1188 lines
51 KiB
C++

#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 <QMessageBox>
#include <QPushButton>
#include <QJsonParseError>
#include <Qt>
#include <QScopedPointer>
#include "message_handler.h"
#include "plugins/interfaces.h"
#include "ismas/ismas_client.h"
#include "progress_event.h"
#include "mainwindow.h"
#include "utils.h"
QString const Worker::UPDATE_STEP_OK ( " [ ok]");
QString const Worker::UPDATE_STEP_DONE ( " [done]");
QString const Worker::UPDATE_STEP_WRONG ( "[WRONG]");
QString const Worker::UPDATE_STEP_FAIL ( " [FAIL]");
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
using UPDATE_STEP = Worker::UPDATE_STEP;
const QMap<UPDATE_STEP, const char*> Worker::smap (
std::initializer_list<std::pair<UPDATE_STEP, const char*>>{
#define INSERT_ELEMENT(p) std::pair(p, #p)
INSERT_ELEMENT(UPDATE_STEP::STARTED),
INSERT_ELEMENT(UPDATE_STEP::CHECK_REPOSITORY),
INSERT_ELEMENT(UPDATE_STEP::CHECK_REPOSITORY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECK_REPOSITORY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::CHECK_SANITY),
INSERT_ELEMENT(UPDATE_STEP::CHECK_SANITY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECK_SANITY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::CLONE_REPOSITORY),
INSERT_ELEMENT(UPDATE_STEP::CLONE_REPOSITORY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CLONE_REPOSITORY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_REPOSITORY),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_REPOSITORY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_REPOSITORY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::CHECK_ISMAS_TRIGGER),
INSERT_ELEMENT(UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE),
INSERT_ELEMENT(UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER),
INSERT_ELEMENT(UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_BRANCH),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECKOUT_BRANCH_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_REPOSITORY),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_REPOSITORY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES),
INSERT_ELEMENT(UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::CHECK_FOR_REPOSITORY_CHANGES_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::FILES_TO_UPDATE),
INSERT_ELEMENT(UPDATE_STEP::FILES_TO_DOWNLOAD),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMANDS),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_1),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_2),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_3),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_4),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_5),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_6),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_7),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_8),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_9),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_LAST),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY),
INSERT_ELEMENT(UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::SAVE_LOGS),
INSERT_ELEMENT(UPDATE_STEP::SAVE_LOGS_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::SAVE_LOGS_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::SEND_LAST_VERSION),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_SUCCEEDED),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_FAILED),
INSERT_ELEMENT(UPDATE_STEP::UPDATE_ACTIVATED),
INSERT_ELEMENT(UPDATE_STEP::FINISHED),
INSERT_ELEMENT(UPDATE_STEP::DEBUG),
INSERT_ELEMENT(UPDATE_STEP::ERROR)
#undef INSERT_ELEMENT
});
Worker *Worker::instance = nullptr;
Worker::Worker(int customerNr,
int machineNr,
int zoneNr,
QString repositoryUrl,
QString branchName,
QString pluginDir,
QString pluginName,
QString workingDirectory,
bool noUpdatePsaHardware,
bool alwaysDownloadConfig,
bool alwaysDownloadDC,
bool dryRun,
QObject *parent,
char const *serialInterface,
char const *baudrate)
: m_customerNr(customerNr)
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
, m_machineNr(machineNr)
, m_zoneNr(zoneNr)
, m_pluginDir(pluginDir)
, m_pluginName(pluginName)
, m_workingDirectory(workingDirectory)
, m_branchName(branchName)
, m_customerRepositoryPath(QString("%1/%2.git").arg(repositoryUrl).arg(m_customerNrStr))
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
, m_noUpdatePsaHardware(noUpdatePsaHardware)
, m_alwaysDownloadConfig(alwaysDownloadConfig)
, m_alwaysDownloadDC(alwaysDownloadDC)
, m_dryRun(dryRun)
, m_parent(parent)
, m_serialInterface(serialInterface)
, m_baudrate(baudrate)
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
, m_osVersion(getOsVersion())
, m_atbqtVersion(getATBQTVersion())
, m_atbUpdateToolVersion(getATBUpdateToolVersion())
, m_cpuSerial(getCPUSerial())
, 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)
, m_filesToUpdate()
, m_updateProcessRunning(true)
, m_mainWindow(nullptr) /* contains plugin */
//, m_withoutIsmasDirectPort(true) /* useful for testing */ {
, m_withoutIsmasDirectPort(false) /* useful for testing */
// IMPORTANT: allocate m_update here, otherwise the connects() inside of
// Update might not work: keep in mind that worker (this) is a thread without
// an own event-loop.
, m_update(new Update(this,
QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr),
m_customerNrStr, m_branchName, m_pluginDir,
m_pluginName, m_workingDirectory)) {
// TODO: turn object into singleton
instance = this;
this->setObjectName("worker-object");
QDir::setCurrent(m_workingDirectory);
m_apismVersion = getAPISMYoctoVersion();
}
Worker::~Worker() {
if (m_update) {
qCritical() << "DELETE UPDATE";
delete m_update;
m_update = nullptr;
}
}
void Worker::displayProgressInMainWindow(int progress) {
if (m_mainWindow) {
QApplication::postEvent(m_mainWindow,
new ProgressEvent(this, progress));
}
}
void Worker::setProgress(int progress) {
m_ismasClient.setProgressInPercent(progress);
displayProgressInMainWindow(progress);
}
void Worker::startProgressLoop() {
displayProgressInMainWindow(MainWindow::START_PROGRESS_LOOP);
}
void Worker::stopProgressLoop() {
displayProgressInMainWindow(MainWindow::STOP_PROGRESS_LOOP);
}
static std::once_flag once;
void Worker::run() {
// user should not start the update process several times
std::call_once(once, &Worker::privateUpdate, this);
}
bool Worker::isRepositoryCorrupted() {
QDir customerRepository(m_customerRepository);
if (customerRepository.exists()) {
QDir customerRepositoryGit(QDir::cleanPath(m_customerRepository + QDir::separator() + ".git/"));
if (!m_gc.gitFsck()) {
// should never happen
Utils::printCriticalErrorMsg("CORRUPTED CUSTOMER REPOSITORY: GIT_FSCK FAILED");
return true;
}
// .git-directory inside git-repository does not exist, which means the
// git-repository is corrupted -> remove it and start from scratch
if (!customerRepositoryGit.exists()) {
// should never happen
Utils::printCriticalErrorMsg("CORRUPTED CUSTOMER REPOSITORY .GIT DOES NOT EXIST");
return true;
}
}
return false;
}
bool Worker::repairCorruptedRepository() {
QDir customerRepository(m_customerRepository);
if (!customerRepository.removeRecursively()) {
Utils::printCriticalErrorMsg("ERROR REMOVING CORR. CUST-REPOSITORY");
//m_updateStatus = UpdateStatus(UPDATE_STATUS::REMOVE_GIT_REPOSITORY_FAILED,
// QString("REMOVAL OF GIT-REPOSITORY %1 FAILED").arg(m_customerRepository));
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") +
// m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
// m_updateStatus.m_statusDescription));
//emit showErrorMessage("apism sanity check", m_updateStatus.m_statusDescription);
return false;
}
return true;
}
void Worker::privateUpdate() {
if (!m_mainWindow) {
Utils::printCriticalErrorMsg("m_mainWindow NOT SET");
return;
}
QString func(__PRETTY_FUNCTION__);
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::STARTED));
QScopedPointer<UpdateProcessRunning> upr(new UpdateProcessRunning(this));
QDir customerRepository(m_customerRepository);
QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
CONSOLE() << UPDATE_STEP::CHECK_SANITY;
m_clone = false;
m_repairClone = false;
m_initialClone = false;
// the customer repository is cloned or
// repaired/re-cloned without checking the
// ISMAS-trigger (WAIT-)button.
// Case 1: no existing repository:
// if there was a sane repository
// available, then the trigger-button is
// checked:
// 1: trigger == WAIT: then
// have been activated in ISMAS.
bool continueUpdate = true; // check if git-clone command has timed-out,
// resulting in a corrupted git-repository, which
// does not contain an ./etc-directory
if (isRepositoryCorrupted()) { // a not-existing repository is not meant
// to be corrupted
CONSOLE() << UPDATE_STEP::CHECK_SANITY_FAILURE;
if ((continueUpdate = repairCorruptedRepository()) == true) {
m_repairClone = true;
CONSOLE() << UPDATE_STEP::REPOSITORY_RECOVERED_SUCCESS;
} else {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::REPOSITORY_RECOVERED_FAILURE));
return;
}
}
CONSOLE() << UPDATE_STEP::CHECK_SANITY_SUCCESS;
if (continueUpdate) {
if ((continueUpdate = customerRepository.exists()) == false) {
m_initialClone = (m_repairClone == false);
GUI() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY);
for (int i = 0; i < 5; ++i) { // try to checkout git repository
setProgress(i); // and switch to branch
if (m_gc.gitCloneAndCheckoutBranch()) {
if (!isRepositoryCorrupted()) {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY_SUCCESS));
continueUpdate = true;
m_clone = true;
break;
}
}
QThread::sleep(1); // maybe git needs more time
}
if (continueUpdate == false) {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CLONE_REPOSITORY_FAILURE));
return;
}
Q_ASSERT_X(m_clone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "clone failed");
} else {
Q_ASSERT_X(!m_clone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_clone not false");
Q_ASSERT_X(!m_initialClone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_initialClone not false");
Q_ASSERT_X(!m_repairClone, (func + QString(":%1").arg(__LINE__)).toStdString().c_str(), "m_repairClone not false");
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY;
if (isRepositoryCorrupted()) {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_FAILURE));
return;
}
}
}
CONSOLE() << UPDATE_STEP::CHECK_REPOSITORY_SUCCESS;
setProgress(_CHECKOUT_REPOSITORY_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// CHECK UPDATE TRIGGER
//
////////////////////////////////////////////////////////////////////////////
m_ismasTriggerActive = false;
if ((continueUpdate = updateTriggerSet()) == false) {
if (m_initialClone) {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::INITIAL_CLONE_WITHOUT_ACTIVE_ISMAS_TRIGGER));
}
return;
} else {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::INITIAL_CLONE_WITH_ACTIVE_ISMAS_TRIGGER));
}
if (m_ismasTriggerActive == false) {// make it explicit again: only if the
// ismas trigger is active ('WAIT'),
// then proceed
return;
}
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS));
setProgress(_CHECK_ISMAS_TRIGGER_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// CHECK-OUT BRANCH
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = customerEnvironment()) == false) {
return;
}
CONSOLE() << UPDATE_STEP::CHECKOUT_BRANCH_SUCCESS;
setProgress(_CHECKOUT_BRANCH_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// COMPUTE CHANGED FILES OF CUSTOMER REPOSITORY
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = filesToUpdate()) == false) {
return;
}
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_REPOSITORY_SUCCESS));
setProgress(_UPDATE_REPOSITORY_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// EXECUTE OPKG COMMANDS
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = execOpkgCommands()) == false) {
return;
}
GUI() << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS);
setProgress(_EXEC_OPKG_COMMAND_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// UPDATE THE PSA USING THE CHANGED FILES
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = downloadFilesToPSAHardware()) == false) {
return;
}
GUI() << (CONSOLE() << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS);
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// (R)SYNC THE REPOSITORY WITH THE LOCAL FILEYSTEM
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = syncCustomerRepositoryAndFS()) == false) {
return;
}
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS));
setProgress(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// FUTURE: SAVE LOG FILES
//
////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = saveLogFile()) == false) {
return;
}
// ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SAVE_LOGS_SUCCESS));
setProgress(_SAVE_LOGS_SUCCESS);
////////////////////////////////////////////////////////////////////////////
//
// FINAL MESSAGES (PART 1)
//
////////////////////////////////////////////////////////////////////////////
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_SUCCEEDED));
setProgress(_UPDATE_SUCCEEDED);
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_ACTIVATED));
setProgress(_UPDATE_ACTIVATED);
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::FINISHED));
setProgress(_FINISHED);
////////////////////////////////////////////////////////////////////////////
//
// FINAL MESSAGES (PART 2): SEND-LAST-VERSION
// (destructor of struct UpdateProcessRunning)
//
////////////////////////////////////////////////////////////////////////////
}
bool Worker::updateTriggerSet() {
// repository is existent and not corrupted. check now if the ISMAS-trigger
// (WAIT-button) is activated even in case of initial checkout
static const QString func = "UPDATE-TRIGGER-SET";
if (m_withoutIsmasDirectPort) { // useful for testing
return true;
}
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER));
QString triggerValue("NOT CHECKED YET");
for (int repeat = 1; repeat <= 100; ++repeat) {
if (repeat > 1) {
int const startMs = QTime::currentTime().msecsSinceStartOfDay();
int const durationMs = QTime::currentTime().msecsSinceStartOfDay() - startMs;
QString const &s = QString("elapsed: %1.%2s").arg(durationMs / 1000).arg(durationMs % 1000);
CONSOLE(QStringList(func) << s) << UPDATE_STEP::DEBUG;
} else {
CONSOLE(QStringList(func) << QString("-> REPEAT=%1").arg(repeat)) << UPDATE_STEP::DEBUG;
}
if ((repeat % 10) == 0) {
CONSOLE(QStringList(func) << "RESTART APISM") << UPDATE_STEP::DEBUG;
Command c("systemctl restart apism");
if (c.execute("/tmp")) {
QThread::sleep(20); // give APISM some time to reconnect
CONSOLE(QStringList(func) << "RESTART APISM DONE") << UPDATE_STEP::DEBUG;
}
}
if (std::optional<QString> result
= IsmasClient::sendRequestReceiveResponse(
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_ISMASPARAMETER#J={}")) {
QString const &msg = QString("APISM RESPONSE(%1)=(").arg(repeat) + result.value() + ")";
CONSOLE(QStringList(func) << msg) << UPDATE_STEP::DEBUG;
QJsonParseError parseError;
QJsonDocument document(QJsonDocument::fromJson(result.value().toUtf8(), &parseError));
if (parseError.error != QJsonParseError::NoError) {
QStringList lst(QString("INVALID JSON MSG: PARSING FAILED (json=<START>%1<END> error=[%2] str=[%3] offset=[%4])")
.arg(msg)
.arg(parseError.error)
.arg(parseError.errorString())
.arg(parseError.offset));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
if (!document.isObject()) {
QStringList lst(QString("not a json-object %1").arg(result.value()));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
QJsonObject obj = document.object();
// always look for an 'error' first
if (obj.contains("error")) {
QStringList lst(obj.value("error").toString());
CONSOLE(QStringList(lst)) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE;
QThread::sleep(6);
continue;
}
// sanity check: cust_nr and machine_nr of PSA correct ?
// note: this check has to be done here, as the cust_nr and the machine_nr
// of the PSA are sent by ISMAS.
if (obj.contains("Dev_ID")) {
QJsonValue v = obj.value("Dev_ID");
if (v.isObject()) {
QJsonObject obj = v.toObject();
if (obj.contains("Custom_ID") && obj.contains("Device_ID")) {
int const customerNr = obj.value("Custom_ID").toInt(-1);
int const machineNr = obj.value("Device_ID").toInt(-1);
if (customerNr != m_customerNr) {
QStringList lst(QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)")
.arg(customerNr).arg(m_customerNr));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
if (machineNr != m_machineNr) {
QStringList lst(QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)")
.arg(machineNr).arg(m_machineNr));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst("Dev_ID DOES NOT CONTAIN Custom_ID AND/OR Device_ID");
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst("Dev_ID KEY NOT A JSON-OBJECT");
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst("Dev_ID KEY NOT AVAILABLE");
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
if (obj.contains("Fileupload")) {
QJsonValue v = obj.value("Fileupload");
if (v.isObject()) {
obj = v.toObject();
if (obj.contains("TRG")) {
if ((triggerValue = obj.value("TRG").toString()) == "WAIT") {
m_ismasTriggerActive = true;
return m_ismasTriggerActive;
} else
if (QRegExp("\\s*").exactMatch(triggerValue)) { // check for whitespace
QStringList lst("empty update trigger");
if (m_clone) {
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE);
// if the customer repository has just been cloned
break; // it is OK the ISMAS trigger might not be 'WAIT'
} else {
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
}
QThread::sleep(6);
continue;
} else {
// if the download-button once has the wrong value, it will never recover
if (m_clone) {
GUI() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER_WRONG_VALUE);
} else {
QStringList lst(QString("TRIGGER-VALUE=<%1> NOT 'WAIT'").arg(triggerValue));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
}
break;
}
} else {
QStringList lst("TRG key not available");
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst("Fileupload not a json-object");
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst(QString("Fileupload not available"));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
break;
}
} else {
QStringList lst = QStringList(QString("no ISMAS response"));
GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE);
QThread::sleep(6);
}
}
if (m_initialClone == false) {
if (!triggerValue.contains("WAIT", Qt::CaseInsensitive)) {
QStringList lst(QString("ISMAS_UPDATE-TRIGGER-NOT-SET-OR-WRONG: VALUE=(") + triggerValue + ")");
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER_FAILURE));
}
}
return false;
}
bool Worker::customerEnvironment() {
// configure customer environment -> checkout branch in case someone has
// changed the zone_nr
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::CHECKOUT_BRANCH));
if (QDir(m_customerRepository).exists()) {
if (m_gc.gitCheckoutBranch()) {
return true;
} else {
QStringList lst(QString("CHECKOUT OF " + m_customerRepository + "FAILED"));
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECKOUT_BRANCH_FAILURE));
}
} else {// cannot happen
QStringList lst(QString(m_customerRepository + " DOES NOT EXIST"));
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::CHECKOUT_BRANCH_FAILURE));
}
return false;
}
bool Worker::filesToUpdate() {
// determine which files has to be updated: either sent to the hardware or
// rsynced with the filesystem in case of tariff-files
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_REPOSITORY));
// always execute contents of opkg_commands-file
m_filesToUpdate << "etc/psa_update/opkg_commands";
if (m_alwaysDownloadConfig) {
#if 0
QStringList lst(QString("m_alwaysDownloadConfig NOT TESTED"));
CONSOLE(lst) << UPDATE_STEP::UPDATE_REPOSITORY;
// always download all json-config files, even if none of them have been
// changed in the git repository. useful for first installation.
QDir dir(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_config"));
if (dir.exists()) {
QStringList jsons = dir.entryList(QStringList() << "DC2C*.json", QDir::Files);
if (!jsons.isEmpty()) {
m_filesToUpdate << jsons;
}
}
#endif
}
if (m_alwaysDownloadDC) {
#if 0
QStringList lst(QString("m_alwaysDownloadDC NOT TESTED"));
CONSOLE(lst) << UPDATE_STEP::UPDATE_REPOSITORY;
// always download the last dc-binary, even if not changed in the
// git repository. useful for first installation.
QDir dir(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_update"));
if (dir.exists()) {
QStringList dc = dir.entryList(QStringList() << "dc2c*.bin", QDir::Files,
QDir::SortFlag::Time | QDir::SortFlag::Reversed);
if (!dc.isEmpty()) {
m_filesToUpdate << dc.first();
}
}
#endif
}
if (std::optional<QString> changes = m_gc.gitPull()) {
if (!changes.value().contains("Already up to date")) {
if (std::optional<QStringList> changedFileNames = m_gc.gitDiff(changes.value())) {
m_filesToUpdate << changedFileNames.value();
}
}
m_filesToUpdate.removeDuplicates();
qCritical() << __PRETTY_FUNCTION__ << "FILES-TO-UPDATE" << m_filesToUpdate;
GUI(m_filesToUpdate) << (CONSOLE(m_filesToUpdate) << UPDATE_STEP::FILES_TO_UPDATE);
setProgress(_FILES_TO_UPDATE);
} else {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::UPDATE_REPOSITORY_FAILURE));
return false;
}
return true;
}
bool Worker::computeFilesToDownload() {
m_filesToDownload.clear();
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
QString const fName = m_filesToUpdate.at(i);
if (fName.contains("DC2C_print", Qt::CaseInsensitive) ||
fName.contains("DC2C_device", Qt::CaseInsensitive) ||
fName.contains("DC2C_conf", Qt::CaseInsensitive) ||
fName.contains("DC2C_cash", Qt::CaseInsensitive)) {
m_filesToDownload << fName; // download printer-config-files
} else {
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
if (fName.contains(version)) {
m_filesToDownload << fName; // download device controller
}
}
}
return (m_filesToDownload.size() > 0);
}
bool Worker::execOpkgCommands() {
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
QString const fName = m_filesToUpdate.at(i);
if (fName.contains("opkg_commands", Qt::CaseInsensitive)) {
GUI() << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMANDS);
// execute opkg commands
if (QDir::setCurrent(m_customerRepository)) {
QFile f(fName);
if (f.exists()) {
if (f.open(QIODevice::ReadOnly)) {
QTextStream in(&f);
m_opkgCommands.clear();
bool executeOpkgCommandFailed = false;
while (!in.atEnd()) {
QString line = in.readLine();
static const QRegularExpression comment("^\\s*#.*$");
if (line.indexOf(comment, 0) == -1) {
// found opkg command
QString opkgCommand = line.trimmed();
if (!executeOpkgCommand(opkgCommand)) {
executeOpkgCommandFailed = true;
} else {
QString cmd = "\n " + opkgCommand;
emit appendText(cmd);
m_opkgCommands << cmd;
QStringList const opkgLst(opkgCommand);
QStringList const cmdLst(cmd);
switch(m_opkgCommands.size()) {
case 1:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_1));
setProgress(_EXEC_OPKG_COMMAND_1);
break;
case 2:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_2));
setProgress(_EXEC_OPKG_COMMAND_2);
break;
case 3:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_3));
setProgress(_EXEC_OPKG_COMMAND_3);
break;
case 4:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_4));
setProgress(_EXEC_OPKG_COMMAND_4);
break;
case 5:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_5));
setProgress(_EXEC_OPKG_COMMAND_5);
break;
case 6:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_6));
setProgress(_EXEC_OPKG_COMMAND_6);
break;
case 7:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_7));
setProgress(_EXEC_OPKG_COMMAND_7);
break;
case 8:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_8));
setProgress(_EXEC_OPKG_COMMAND_8);
break;
case 9:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_9));
setProgress(_EXEC_OPKG_COMMAND_9);
break;
default:
ISMAS(opkgLst) << (GUI(cmdLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_LAST));
setProgress(_EXEC_OPKG_COMMAND_LAST);
}
}
}
}
f.close();
if (!executeOpkgCommandFailed) {
if (m_opkgCommands.size() > 0) {
m_displayIndex = 1;
GUI() << UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS;
setProgress(_EXEC_OPKG_COMMAND_SUCCESS);
}
} else {
m_displayIndex = 1;
GUI() << UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE;
setProgress(_EXEC_OPKG_COMMAND_FAILURE);
return false;
}
}
}
}
}
}
return true;
}
bool Worker::downloadFilesToPSAHardware() {
m_displayIndex = 0;
GUI(m_filesToDownload) << (CONSOLE(m_filesToDownload) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE);
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE);
if (m_noUpdatePsaHardware == false) {
if (computeFilesToDownload()) {
CONSOLE(m_filesToDownload) << UPDATE_STEP::FILES_TO_DOWNLOAD;
//m_update = new Update(this,
// QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr),
// m_customerNrStr, m_branchName, m_pluginDir,
// m_pluginName, m_workingDirectory);
return m_update->doUpdate(m_displayIndex, m_filesToDownload);
} else {
CONSOLE(QStringList("NO FILES TO DOWNLOAD TO PSA-HW")) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE;
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE);
}
}
return true;
}
bool Worker::syncCustomerRepositoryAndFS() {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY));
if (QDir(m_customerRepository).exists()) {
if (QDir::setCurrent(m_customerRepository)) {
Command md("bash");
if (!md.execute(m_customerRepository,
QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/dc /etc/psa_tariff")) {
qCritical() << "COULD NOT EXECUTE '" << md.command() << "' exitCode=(" << md.exitCode() << ")";
}
QString const params("-v "
"--recursive "
"--progress "
"--checksum "
"--exclude=.* "
"--include=*.bin "
"--include=*.json "
"--include=*.ini");
QStringList cmds;
if (QDir(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/")).exists()) {
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
Utils::printInfoMsg(QString("CONFIGURED SYNCING TO /ETC"));
}
if (QDir(QDir::cleanPath(m_customerRepository + QDir::separator() + "opt/")).exists()) {
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
Utils::printInfoMsg(QString("CONFIGURED SYNCING TO /OPT"));
}
QString cmd;
bool error = false;
foreach (cmd, cmds) {
if (!error) {
Command c("bash");
qInfo() << "EXECUTING CMD..." << cmd;
Utils::printInfoMsg(QString("EXECUTING CMD %1...").arg(cmd));
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
QStringList result = c.getCommandResult().split('\n');
QString const &p1 = "send_files mapped ";
QString const &p2 = "of size";
for (int i = 0; i < result.size(); ++i) {
QString line = result.at(i);
qInfo() << line;
// "send_files mapped etc/psa_tariff/tariff01.json of size 19339"
int sendFilesAtPos = line.indexOf(p1);
int ofSizeAtPos = line.indexOf(p2);
if (sendFilesAtPos != -1 && ofSizeAtPos != -1) {
sendFilesAtPos += p1.length();
QString const &s = line.mid(sendFilesAtPos, ofSizeAtPos - sendFilesAtPos).trimmed();
//m_updateStatus = UpdateStatus(UPDATE_STATUS::RSYNC_FILE_SUCCESS,
// QString("RSYNC FILE ") + s.split("/").last() +
// " LAST-COMMIT: " + m_gc.gitLastCommit(s));
//IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
// QString("#M=APISM#C=CMD_EVENT#J=") +
// m_ismasClient.rsyncFile(m_updateStatus.m_statusDescription, ""));
}
}
} else {
Utils::printCriticalErrorMsg(QString("CMD ") + cmd + " FAILED: "
+ c.getCommandResult() + QString(" EXIT_CODE=(%1)").arg(c.exitCode()));
error = true;
}
}
}
if (!error) {
// now check tariff-files in etc and /etc/psa_tariff
QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff"));
QDir dir2("/etc/psa_tariff");
if (Utils::sameFilesInDirs(dir1, dir2)) {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS));
setProgress(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
return true;
}
}
}
}
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE));
setProgress(_SYNC_CUSTOMER_REPOSITORY_FAILURE);
return false;
}
bool Worker::saveLogFile() {
// ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SAVE_LOGS));
// ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SAVE_LOGS_FAILURE));
return true;
}
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::getATBUpdateToolYoctoVersion() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A1 atbupdatetool | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.3.9+git0+226553a8ab-r0
}
}
return "N/A";
}
QString Worker::getAPISMYoctoVersion() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A1 apism | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.4.1.0-r4
}
}
return "N/A";
}
QString Worker::getATBUpdateToolYoctoInstallationStatus() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A3 atbupdatetool | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2,3,4)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.3.9+git0+226553a8ab-r0
}
}
return "N/A";
}
QString Worker::getAPISMYoctoInstallationStatus() {
if (QFile::exists("/var/lib/opkg/status")) {
QString const cmd = QString("echo -n $(cat /var/lib/opkg/status | grep -A3 apism | tail -n 1 | cut -d':' -f2 | cut -d' ' -f2,3,4)");
Command c("bash");
if (c.execute("/tmp", QStringList() << "-c" << cmd)) {
return c.getCommandResult(); // 1.3.9+git0+226553a8ab-r0
}
}
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::getATBUpdateToolVersion() const {
return APP_EXTENDED_VERSION;
}
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");
Update const *up = update();
if (up) {
hwinf const *caPlugin = up->hw();
if (caPlugin) {
caPlugin->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 = caPlugin->dc_getHWversion().toUtf8();
sw = caPlugin->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;
}
bool Worker::executeOpkgCommand(QString opkgCommand) {
Command c(opkgCommand);
if (c.execute(m_workingDirectory)) {
QString const r = c.getCommandResult();
Utils::printInfoMsg(QString("EXECUTE OPKG COMMAND %1 OK: %2")
.arg(opkgCommand)
.arg(c.getCommandResult()));
return true;
} else {
Utils::printCriticalErrorMsg(QString("EXECUTE OPKG COMMAND %1 FAILED")
.arg(opkgCommand));
}
return false;
}
PSAInstalled Worker::getPSAInstalled() {
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 tariffRepoDir("etc/psa_tariff");
QString opkgRepoDir("etc/psa_update");
QString const &absPathNameRepositoryOpkg = QDir::cleanPath(opkgRepoDir + QDir::separator() + "opkg_commands");
QString absPathName;
QString absPathNameRepository;
psaInstalled.versionInfo.lastCommit = "";
psaInstalled.versionInfo.reason = "";
psaInstalled.versionInfo.created = "";
QStringList versionInfo = m_gc.gitShowReason(m_branchName);
if (versionInfo.size() == 3) {
psaInstalled.versionInfo.lastCommit = versionInfo.at(0);
psaInstalled.versionInfo.reason = versionInfo.at(1);
psaInstalled.versionInfo.created = versionInfo.at(2);
}
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);
absPathNameRepository = QDir::cleanPath(tariffRepoDir + QDir::separator() + psaInstalled.tariff.name);
psaInstalled.tariff.lastCommit = m_gc.gitLastCommit(absPathNameRepository);
psaInstalled.tariff.size = getFileSize(absPathName);
psaInstalled.tariff.zone = m_zoneNr;
psaInstalled.tariff.loadTime = Utils::getTariffLoadTime(absPathName);
}
psaInstalled.tariff.project = "Szeged";
psaInstalled.tariff.info = "N/A";
psaInstalled.tariff.version = "N/A";
psaInstalled.hw.linuxVersion = getOsVersion();
psaInstalled.hw.cpuSerial = m_cpuSerial;
psaInstalled.opkg.blob = m_gc.gitBlob(absPathNameRepositoryOpkg);
// psaInstalled.opkg.size = getFileSize(absPathNameRepositoryOpkg);
// psaInstalled.opkg.loadTime = Utils::getTariffLoadTime(absPathNameRepositoryOpkg);
psaInstalled.opkg.lastCommit = m_gc.gitLastCommit(absPathNameRepositoryOpkg);
psaInstalled.dc.versionHW = deviceControllerVersionHW;
psaInstalled.dc.versionSW = deviceControllerVersionSW;
psaInstalled.dc.gitBlob = "N/A";
psaInstalled.dc.gitLastCommit = "N/A";
psaInstalled.dc.size = -1;
psaInstalled.sw.apismVersion = getAPISMYoctoVersion();
psaInstalled.sw.atbQTVersion = getATBQTVersion();
psaInstalled.sw.atbUpdateToolVersion = m_atbUpdateToolVersion;
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);
}
return psaInstalled;
}