5 Commits

13 changed files with 2988 additions and 1465 deletions

View File

@@ -6,7 +6,7 @@ plugin-directory="/usr/lib/"
working-directory="/opt/app/tools/atbupdate/"
[PLUGINS]
plugin-name="libCAmaster.so"
plugin-name="libCAslave.so"
[FLAGS]
no-psa-hardware-update=false
@@ -14,5 +14,5 @@ dry-run=false
extended-version=false
yocto-version=false
yocto-install=false
always-download-config=true
always-download-config=false
always-download-dc=false

View File

@@ -53,7 +53,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
# local filesystem, json-files will be downloaded to firmware.
# The device-controller firmware will be handled in a later version.
# 1.3.15: Bug fixes found during testing.
# Do not disable Exit-button during update-process.
# Don't disable Exit-button during update-process.
# Removed worker-thread with an own event-loop: only the GUI thread
# has an event loop. Tested JSON-downloads several times successfully
# (using the slave lib where the CA helper tool was active as master).
@@ -64,34 +64,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
# given in ATBUpdateTool.ini can be overwritten on the command-line.
# 1.3.18: Bug fixes found during testing.
# 1.3.19: Bug fixes found during testing.
VERSION="1.3.20"
# 1.3.20: Bug fixes found during testing.
# 1.3.21: Bug fixes found during testing:
# Fix directory of ATBUpdateTool.ini to be the working directory of
# the application rather than just ".".
# Check existance of etc-directory inside customer repository.
# Check for valid ISMAS trigger (button) 15x (=90s).
# NOTE: if the customer repository is cloned (or repaired and cloned
# again), and if the settings always-download-config=true and
# always-download-dc=true in the ATBUpdateTool.ini file, the download
# the printer-json files and the device controller file, even without
# an activated ISMAS trigger (button). The tariff-files are rsynced to
# the local filesystem for such clone.
# Set new filename for device controller: dc2c.bin.
# 1.3.22: Bug fixes found during testing:
# Fix the path-names of the json-files and the device-controller.
# Set automatic download of json-file in ATBUpdateTool.ini file for
# a fresh clone of the repository.
# 1.3.23: Added a 'break' to prevent a possible endless loop when checking if
# the device is alive.
#
# NOTE: The versioning info has to be shifted up by one version, i.e. what
# happened for 1.3.23 was actually done in 1.3.24.
# 1.3.24
#
# 1.3._24_: Special version for szeged using a old dc-controller (4.42):
# Changes:
# (1) the ini-File now uses the libCAmaster.so.
VERSION="1.3._24_"
# PLANNED TODOS:
# 1: Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT.
@@ -122,35 +96,6 @@ VERSION="1.3._24_"
# Stellung des WAIT-Button. Grund: es koennte sein, dass andernfalls ein
# PSA weit hiter anderen steht, und dann ploetzlich einmal alle vorher-
# gehenden Aenderungen anzieht, die gar nicht fuer ihn gemeint waren.
# 10: Bei einer Neuinstallation (Neuhauser) immer JSON files runterladen,
# Tariff-Files syncen (d.h. nur wenn noch kein Repo vorhanden ist), und
# zwar auch ohne WAIT-Button.
# 11: Das Edit-Fenster teilen um die Anzeige zu verbessern.
# 12: Bei einem Update muss immer ersichtlich sein, warum es ueberhaupt
# angestossen wurde. Steht kein "WAIT" im ISMAS-Trigger, dann kann man
# davon ausgehen, dass es sich um ein automatisches Update handelt.
# In jedem Fall wird bei einem automatischen Update, bei dem der WAIT-
# Button nicht gesetzt war, ein "OK" gesendet, falls sonst nichts weiter
# zu tun ist. Beachte aber: wir haben auch noch den Fall, dass eine SD-
# Karte gesteckt wird. In diesem Fall wird ein komplettes Update gefahren,
# und zwar explizit auch ohne WAIT-Button.
# Am Ende eines Updates steht im ISMAS entweder ein "OK" oder ein "FAIL".
# 13: SendLastVersion: fuer jedes erfolgreich installierte Paket eine
# Send-Last-Version-Nachricht an ISMAS. Dadurch entsteht im ISMAS eine
# History (Christian darueber informieren).
# 14: Installiert werden nur Dateien, die neu sind oder geaendert wurden.
# Nicht etwas Dateien, die geloescht wurden: sicherstellen, dass man hier
# immer direkt im repository arbeitet, nicht auf dem Filesystem.
# Ferner: der DeviceController heisst dc2c.bin, auch fuer die Jsons
# sind Dtandard-Namen vergeben. Alternativ: alle vorhandenen Jsons
# werden runtergeladen: Thomas ist eh fuer deren Inhalte verantworlich.
# WICHTIG: immer ueberpruefen, ob die Dateien im Customer-Repository
# wirklich die richtigen Dateien sind.
# 15: Der WAIT-Button laesst sich auf WAIT zuruecksetzen (etwa wenn git
# selber Probleme hatte).
# 16: Der Download-Thread sollte sowohl die auto-Variable auf false setzen
# als auch den cycle-Timer stoppen, damit sichergestellt ist, dass der
# Download des DC nicht gestoert wird.
win32 {

View File

@@ -87,7 +87,7 @@ void CommandLineParser::configure() {
m_repositoryUrlOption.setDefaultValue("https://git.mimbach49.de/GerhardHoffmann");
m_parser.addOption(m_repositoryUrlOption);
m_iniFileDirectoryOption.setDefaultValue(QCoreApplication::applicationDirPath());
m_iniFileDirectoryOption.setDefaultValue(".");
m_parser.addOption(m_iniFileDirectoryOption);
m_iniFileNameOption.setDefaultValue("ATBUpdateTool.ini");
@@ -117,10 +117,10 @@ void CommandLineParser::configure() {
m_extendedVersionOption.setDefaultValue("false");
m_parser.addOption(m_extendedVersionOption);
m_yoctoVersionOption.setDefaultValue("false");
m_yoctoVersionOption .setDefaultValue("false");
m_parser.addOption(m_yoctoVersionOption);
m_yoctoInstallStatusOption.setDefaultValue("false");
m_yoctoInstallStatusOption .setDefaultValue("false");
m_parser.addOption(m_yoctoInstallStatusOption);
}
@@ -128,6 +128,7 @@ void CommandLineParser::readSettings() {
QString const iniFileDir = m_parser.value(m_iniFileDirectoryOption);
QString const iniFileName = m_parser.value(m_iniFileNameOption);
m_iniFileName = QDir::cleanPath(iniFileDir + QDir::separator() + iniFileName);
if (!m_iniFileName.isEmpty()) {
if (QFile(m_iniFileName).exists()) {
QSettings settings(m_iniFileName, QSettings::IniFormat);

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -793,152 +793,6 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
return buf;
}
#if 0
// prepare
QString IsmasClient::sendLastVersion(UPDATE_COMPONENT updateComponent,
PSAInstalled const &psa) {
static char buf[4096*2];
memset(buf, 0, sizeof(buf));
switch (updateComponent) {
case UPDATE_COMPONENT::TARIFF:
snprintf(buf, sizeof(buf)-1,
"{"
"\"VERSION_INFO\" : {"
"\"UPDATE_REASON\":\"%s\","
"\"CREATED\":\"%s\","
"\"GIT_COMMIT\":\"%s\""
"},"
"\"TARIFF\" : {"
"\"VERSION\" : \"%s\","
"\"PROJECT\" : \"%s\","
"\"ZONE\" : %d,"
"\"INFO\" : \"%s\","
"\"SIZE\" : %d\""
"},"
"}",
psa.tariff.versionInfo.reason.toStdString().c_str(),
psa.tariff.versionInfo.created.toStdString().c_str(),
psa.tariff.versionInfo.lastCommit.toStdString().c_str(),
psa.tariff.version.toStdString().c_str(),
psa.tariff.project.toStdString().c_str(),
psa.tariff.zone,
psa.tariff.info.toStdString().c_str(),
psa.tariff.size);
break;
case UPDATE_COMPONENT::SOFTWARE_ATBQT:
break;
case UPDATE_COMPONENT::SOFTWARE_APISM:
break;
case UPDATE_COMPONENT::SOFTWARE_ATB_UPDATE_TOOL:
break;
case UPDATE_COMPONENT::CONFIG_PTU5_CPU_SERIAL:
break;
case UPDATE_COMPONENT::CONFIG_DEVICE_CONTROLLER:
break;
case UPDATE_COMPONENT::CONFIG_PRINTER:
break;
case UPDATE_COMPONENT::CONFIG_BNA:
break;
case UPDATE_COMPONENT::PLUGIN_ATB_DEVICE_CONTROLLER:
break;
case UPDATE_COMPONENT::PLUGIN_INGENICO_CC:
break;
case UPDATE_COMPONENT::PLUGIN_MOBILISIS_CALC_PRICE:
break;
case UPDATE_COMPONENT::PLUGIN_MOBILISIS_CALC_PRICE_UI:
break;
case UPDATE_COMPONENT::PLUGIN_PRM_CALC_PRICE:
break;
case UPDATE_COMPONENT::PLUGIN_PRM_CALC_PRICE_UI:
break;
case UPDATE_COMPONENT::PLUGIN_TCP_ZVT_CC:
break;
case UPDATE_COMPONENT::OPKG_COMMANDS:
break;
case UPDATE_COMPONENT::HARDWARE_DEVICES:
break;
case UPDATE_COMPONENT::OS:
break;
case UPDATE_COMPONENT::DC2C_CASH_JSON:
break;
case UPDATE_COMPONENT::DC2C_CONF_JSON:
break;
case UPDATE_COMPONENT::DC2C_DEVICE_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT01_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT02_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT03_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT04_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT05_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT06_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT07_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT08_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT09_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT10_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT11_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT12_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT13_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT14_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT15_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT16_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT17_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT18_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT19_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT20_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT21_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT22_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT23_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT24_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT25_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT26_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT27_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT28_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT29_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT30_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT31_JSON:
break;
case UPDATE_COMPONENT::DC2C_PRINT32_JSON:
break;
}
qInfo() << buf;
return buf;
}
#endif
QString IsmasClient::updateOfPSAContinues(QString currentStage,
QString currentStageInfo,
QString const &version) {

View File

@@ -14,7 +14,6 @@ struct PSAInstalled {
} versionInfo;
struct Tariff {
// VersionInfo versionInfo;
QString name;
QString version;
QString project;
@@ -32,7 +31,6 @@ struct PSAInstalled {
} hw;
struct Opkg {
// VersionInfo versionInfo;
int size;
QString blob;
QString lastCommit;
@@ -40,7 +38,6 @@ struct PSAInstalled {
} opkg;
struct DC {
// VersionInfo versionInfo;
QString versionHW;
QString versionSW;
QString gitBlob;
@@ -65,7 +62,6 @@ struct PSAInstalled {
} pluginVersion;
struct DC2C {
// VersionInfo versionInfo;
QString name;
QString blob;
int size;
@@ -198,68 +194,8 @@ public:
QString jsonParseFailed(int resultCode, QString reason, QString const &version = QString());
std::optional<QString> finalResult(int resultCode, QString reason, QString const &version = QString());
// legacy
QString updateOfPSASendVersion(PSAInstalled const &psa);
#if 0
enum class UPDATE_COMPONENT {
TARIFF,
SOFTWARE_ATBQT,
SOFTWARE_APISM,
SOFTWARE_ATB_UPDATE_TOOL,
CONFIG_PTU5_CPU_SERIAL,
CONFIG_DEVICE_CONTROLLER,
CONFIG_PRINTER,
CONFIG_BNA,
PLUGIN_ATB_DEVICE_CONTROLLER,
PLUGIN_INGENICO_CC,
PLUGIN_MOBILISIS_CALC_PRICE,
PLUGIN_MOBILISIS_CALC_PRICE_UI,
PLUGIN_PRM_CALC_PRICE,
PLUGIN_PRM_CALC_PRICE_UI,
PLUGIN_TCP_ZVT_CC,
OPKG_COMMANDS,
HARDWARE_DEVICES,
OS,
DC2C_CASH_JSON,
DC2C_CONF_JSON,
DC2C_DEVICE_JSON,
DC2C_PRINT01_JSON,
DC2C_PRINT02_JSON,
DC2C_PRINT03_JSON,
DC2C_PRINT04_JSON,
DC2C_PRINT05_JSON,
DC2C_PRINT06_JSON,
DC2C_PRINT07_JSON,
DC2C_PRINT08_JSON,
DC2C_PRINT09_JSON,
DC2C_PRINT10_JSON,
DC2C_PRINT11_JSON,
DC2C_PRINT12_JSON,
DC2C_PRINT13_JSON,
DC2C_PRINT14_JSON,
DC2C_PRINT15_JSON,
DC2C_PRINT16_JSON,
DC2C_PRINT17_JSON,
DC2C_PRINT18_JSON,
DC2C_PRINT19_JSON,
DC2C_PRINT20_JSON,
DC2C_PRINT21_JSON,
DC2C_PRINT22_JSON,
DC2C_PRINT23_JSON,
DC2C_PRINT24_JSON,
DC2C_PRINT25_JSON,
DC2C_PRINT26_JSON,
DC2C_PRINT27_JSON,
DC2C_PRINT28_JSON,
DC2C_PRINT29_JSON,
DC2C_PRINT30_JSON,
DC2C_PRINT31_JSON,
DC2C_PRINT32_JSON,
};
QString sendLastVersion(UPDATE_COMPONENT comp, PSAInstalled const &psa);
#endif
private:
static void printDebugMessage(int port, QString const &clientIP, int clientPort,
QString const &message);

View File

@@ -146,7 +146,7 @@ void MainWindow::onEnableExit() {
void MainWindow::onRestartExitTimer() {
m_exitTimer->stop();
m_exitTimer->start(5 * 1000);
m_exitTimer->start(60 * 1000);
scrollDownTextEdit();
ui->updateStatus->setEnabled(false);
@@ -156,6 +156,15 @@ void MainWindow::onQuit() {
m_exitTimer->stop();
int errorCode = 0;
Update *update = m_worker->update();
if (update) {
hwinf *hw = update->hw();
if (hw) {
hw->dcDownloadReportFinished();
hw->dcDownloadFinished();
}
}
qCritical()
<< QString("ON QUIT: CURRENT STEP %1")
.arg(m_worker->getSmap()[m_worker->currentStep()]);

File diff suppressed because it is too large Load Diff

View File

@@ -54,10 +54,6 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
qCritical() << pluginLoader.errorString();
exit(-1);
}
qCritical() << "loadDCPlugin() plugin directory:" << plugInDir.absolutePath();
qCritical() << "loadDCPlugin() plugin file name:" << pluginLoader.fileName();
if (!pluginLoader.isLoaded()) {
qCritical() << pluginLoader.errorString();
exit(-2);
@@ -98,6 +94,7 @@ bool Update::unloadDCPlugin() {
return false;
}
class hwapi;
Update::Update(Worker *worker,
QString customerRepository,
QString customerNrStr,
@@ -122,31 +119,56 @@ Update::Update(Worker *worker,
, m_dryRun(dryRun)
, m_sys_areDCdataValid(false) {
//int tries = 20;
//while ((m_sys_areDCdataValid = m_hw->sys_areDCdataValid()) == false) {
int tries = 20;
while ((m_sys_areDCdataValid = m_hw->sys_areDCdataValid()) == false) {
// must deliver 'true', only then are all data from hwapi valid
// if (--tries < 0) {
// qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-MASTER-PLUGIN NOT CONNECTED";
// break;
// }
// m_hw->dc_autoRequest(true);
// QThread::msleep(500);
//}
if (--tries < 0) {
qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-MASTER-PLUGIN NOT CONNECTED";
}
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
//qCritical() << "UPDATE: m_sys_areDCDataValid ..." << m_sys_areDCdataValid;
qCritical() << "UPDATE: m_sys_areDCDataValid ..." << m_sys_areDCdataValid;
//qInfo() << "UPDATE: m_serialInterface ..." << m_serialInterface;
//qInfo() << "UPDATE: m_baudrate ..." << m_baudrate;
//qInfo() << "UPDATE: m_customerRepository ..." << m_customerRepository;
//qInfo() << "UPDATE: m_customerNr ..........." << m_customerNrStr;
//qInfo() << "UPDATE: m_branchName ..........." << m_branchName;
//qInfo() << "UPDATE: m_pluginName ..........." << m_pluginName;
//qInfo() << "UPDATE: m_workingDirectory ....." << m_workingDir;
QObject const *obj = m_hw->getAPI();
// QObject const *obj = (QObject const *)(hw);
if (!connect(obj,
SIGNAL(hwapi_reportDCDownloadStatus(QString const&)), this,
SLOT(onReportDCDownloadStatus(QString const &)))) {
qCritical() << "ERROR connect() to onReportDCDownloadStatus() failed";
}
if (!connect(obj,
SIGNAL(hwapi_reportDCDownloadSuccess(QString const&)), this,
SLOT(onReportDCDownloadSuccess(QString const &)))) {
qCritical() << "ERROR connect() to onReportDCDownloadSuccess() failed";
}
if (!connect(obj,
SIGNAL(hwapi_reportDCDownloadFailure(QString const &)), this,
SLOT(onReportDCDownloadFailure(QString const &)))) {
qCritical() << "ERROR connect() to onReportDCDownloadFailure() failed";
}
}
Update::~Update() {
}
void Update::onReportDCDownloadStatus(QString const &status) {
emit m_worker->showStatusMessage("DL", status);
}
void Update::onReportDCDownloadSuccess(QString const &msg) {
qCritical() << "msg" << msg;
}
void Update::onReportDCDownloadFailure(QString const &errorMsg) {
qCritical() << "msg" << errorMsg;
}
// br is a index into a table, used for historical reasons.
bool Update::openSerial(int br, QString baudrate, QString comPort) const {
qDebug() << "opening serial" << br << baudrate << comPort << "...";
@@ -266,7 +288,6 @@ bool Update::updateBinary(QString const &fileToSendToDC) {
return false;
#if 0
QFile fn(fileToSendToDC);
if (!fn.exists()) {
// output via CONSOLE() etc
@@ -335,7 +356,6 @@ bool Update::updateBinary(QString const &fileToSendToDC) {
}
return true;
#endif
}
QString Update::jsonType(enum FileTypeJson type) {
@@ -383,32 +403,24 @@ bool Update::downloadJson(enum FileTypeJson type,
templateIdx,
(uint8_t *)ba.data())) {
/*
* Note: the machine id is contained in DC2C_conf.json.
* The idea was to use this to check if the download of
* the json-file was correct. It did not work, as the
* update of the PSA (to reflect a change in the
* machine id) did not happen immediately.
*
m_hw->dc_autoRequest(true);
QThread::msleep(500);
m_hw->dc_autoRequest(true);
QThread::msleep(500);
// testing
m_hw->request_ReadbackMachineID();
QThread::msleep(500);
// testing
m_hw->request_ReadbackMachineID();
QThread::msleep(500);
uint8_t data[64];
memset(data, 0x00, sizeof(data));
uint8_t length = 0;
uint8_t data[64];
memset(data, 0x00, sizeof(data));
uint8_t length = 0;
m_hw->readback_machineIDdata(&length, data);
m_hw->readback_machineIDdata(&length, data);
QThread::msleep(500);
QThread::msleep(500);
QByteArray ba((const char*)data, length);
QByteArray ba((const char*)data, length);
qCritical() << length << "MACHINE ID =" << ba.toHex(':');
*/
qCritical() << length << "MACHINE ID =" << ba.toHex(':');
ret = true;
}
@@ -509,106 +521,64 @@ QStringList Update::getDcSoftAndHardWareVersion() {
<< "DC SW-version not available";
}
QString Update::getFileVersion(QString const& jsonFileName) {
// "version":"15.10.2023 14:55 02.00.06",
static const QRegularExpression re("^.*(\\\"version\\\":)(.*)$");
QString fileVersion;
QFile inputFile(jsonFileName);
if (inputFile.open(QIODevice::ReadOnly)) {
QTextStream in(&inputFile);
while (!in.atEnd()) {
QString line = in.readLine();
QRegularExpressionMatch match;
int idx = line.indexOf(re, 0, &match);
if (idx != -1) {
fileVersion = match.captured(match.lastCapturedIndex());
break;
}
}
inputFile.close();
}
return fileVersion;
}
bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) {
uint8_t jsonNr = 0;
QFileInfo fInfo(jsonFileNames[i]);
if (fInfo.fileName().endsWith("conf.json")) {
jsonNr = 1;
} else
if (fInfo.fileName().endsWith("device.json")) {
jsonNr = 2;
} else
if (fInfo.fileName().endsWith("cash.json")) {
jsonNr = 3;
} else {
QRegularExpressionMatch match;
static const QRegularExpression re("^(.*print)([0-3][0-9])\\.json\\s*$");
int idx = fInfo.fileName().indexOf(re, 0, &match);
if (idx != -1) {
QString captured = match.captured(match.lastCapturedIndex());
bool ok = false;
int n = captured.toInt(&ok);
if (ok) {
jsonNr = n + 4;
}
}
}
if (jsonNr != 0) {
#if 0
m_hw->sys_requestJsonVersions(jsonNr);
QThread::msleep(500);
char buf[64];
memset(buf, 0x00, sizeof(buf));
m_hw->sys_getJsonVersions(jsonNr, buf);
buf[sizeof(buf)-1] = '\0';
QString const installedVersion(buf);
QString const fileVersion = getFileVersion(jsonFileNames[i]);
qCritical() << "installed version:" << installedVersion;
qCritical() << " file version:" << fileVersion;
if (installedVersion == fileVersion) {
}
#endif
} else {
qCritical() << "CANNOT FIND JSON-NR FOR" << jsonFileNames[i];
}
}
return false;
}
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
//if (m_sys_areDCdataValid == false) {
// qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-MASTER-PLUGIN NOT CONNECTED";
// return false;
//}
if (m_sys_areDCdataValid == false) {
qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-MASTER-PLUGIN NOT CONNECTED";
return false;
}
bool res = false;
bool dcDownloadPossible = true;
QList<QString>::const_iterator it;
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
m_worker->startProgressLoop();
QString const &fToWorkOn = QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed());
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
qCritical() << "ABOUT TO START REPORTING THREAD (1)" << fToWorkOn;
if (fToWorkOn.contains(version) && dcDownloadPossible) {
// download for dc possible only once
dcDownloadPossible = false;
m_hw->dcDownloadRequest(fToWorkOn); // initiate download process
// test
m_hw->dcDownloadThreadStart();
if (!m_hw->dcDownloadRunning()) { // may take some time
qCritical() << QDateTime::currentDateTime() << __PRETTY_FUNCTION__
<< QString("line=%1 DOWNLOAD NOT RUNNING").arg(__LINE__);
continue; // wait for reporting thread to start
}
if (!m_hw->dcDownloadReportThreadStart()) { // may take some time
qCritical() << QDateTime::currentDateTime() << __PRETTY_FUNCTION__
<< QString("line=%1 REPORT THREAD NOT RUNNING").arg(__LINE__);
continue; // wait for reporting thread to start
}
if (!m_hw->dcDownloadReportRunning()) { // may take some time
qCritical() << QDateTime::currentDateTime() << __PRETTY_FUNCTION__
<< QString("line=%1 DOWNLOAD REPORT NOT RUNNING").arg(__LINE__);
continue; // reporting events from download thread
}
if (!m_hw->dcDownloadReportFinished()) { // may take some time
qCritical() << QDateTime::currentDateTime() << __PRETTY_FUNCTION__
<< QString("line=%1 DOWNLOAD REPORT THREAD DID NOT FINISH").arg(__LINE__);
m_hw->dcDownloadReportThreadQuit();
continue; // wait for download thread to finish
}
qCritical() << QDateTime::currentDateTime() << __PRETTY_FUNCTION__
<< QString("line=%1 DOWNLOAD SUCCESS").arg(__LINE__);
if (fToWorkOn.contains("dc2c.bin")) {
bool updateBinaryRes = true;
// CONSOLE()
// CONSOLE()
#if 0
m_hw->dc_autoRequest(false);// default: turn auto-request setting off
QThread::sleep(1); // wait to be sure that there are no more
// commands sent to dc-hardware
@@ -637,65 +607,65 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
qInfo() << "dc-firmware-version (NOT UPDATED)" << versions[1];
}
}
#endif
res = updateBinaryRes;
} else {
if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
} else if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
if ((templateIdx < 1) || (templateIdx > 32)) {
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
res = false;
} else {
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
Utils::printInfoMsg(
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
.arg(fToWorkOn)
.arg(templateIdx));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateCashConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res= updateConfig(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateDeviceConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = true;
int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
if ((templateIdx < 1) || (templateIdx > 32)) {
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
res = false;
} else {
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
Utils::printInfoMsg(
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
.arg(fToWorkOn)
.arg(templateIdx));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateCashConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res= updateConfig(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateDeviceConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn));
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
} else {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false;
}
// m_worker->stopProgressLoop();
// m_worker->setProgress(100);
if (res == false) {
break;

View File

@@ -58,7 +58,6 @@ public:
char const *baudrate = "115200");
virtual ~Update() override;
bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
bool checkDownloadedJsonVersions(QStringList const& jsonFileNames);
hwinf *hw() { return m_hw; }
hwinf const *hw() const { return m_hw; }
@@ -88,12 +87,14 @@ private:
bool downloadJson(enum FileTypeJson type, int templateIdx,
QString jsFileToSendToDC) const;
QStringList getDcSoftAndHardWareVersion();
QString getFileVersion(QString const& jsonFile);
private slots:
void readyReadStandardOutput();
void readyReadStandardError();
void finished(int exitCode, QProcess::ExitStatus exitStatus);
void onReportDCDownloadStatus(QString const &status);
void onReportDCDownloadSuccess(QString const &msg);
void onReportDCDownloadFailure(QString const &errorMsg);
};
#endif // UPDATE_H_INCLUDED

View File

@@ -157,7 +157,14 @@ Worker::Worker(int customerNr,
, m_updateProcessRunning(true)
, m_mainWindow(nullptr) /* contains plugin */
//, m_withoutIsmasDirectPort(true) /* useful for testing */ {
, m_withoutIsmasDirectPort(false) /* 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;
@@ -166,9 +173,15 @@ Worker::Worker(int customerNr,
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) {
@@ -214,12 +227,6 @@ bool Worker::isRepositoryCorrupted() {
Utils::printCriticalErrorMsg("CORRUPTED CUSTOMER REPOSITORY .GIT DOES NOT EXIST");
return true;
}
QDir customerRepositoryEtc(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/"));
if (!customerRepositoryEtc.exists()) {
// should never happen
Utils::printCriticalErrorMsg(QString("CORRUPTED CUSTOMER REPOSITORY %1/etc DOES NOT EXIST").arg(m_customerRepository));
return true;
}
}
return false;
}
@@ -340,30 +347,21 @@ void Worker::privateUpdate() {
//
////////////////////////////////////////////////////////////////////////////
m_ismasTriggerActive = false;
if (m_clone == false) {
if ((continueUpdate = updateTriggerSet()) == false) {
return;
} else {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS));
setProgress(_CHECK_ISMAS_TRIGGER_SUCCESS);
}
} else {
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));
}
qCritical() << "**** m_ismasTriggerActive:" << m_ismasTriggerActive;
qCritical() << "**** m_clone:" << m_clone;
if (m_ismasTriggerActive == false) {// make it explicit again: only if the
// ismas trigger is active ('WAIT'),
// then proceed
if (m_clone == false) { // if it is an (initial) clone, then
return; // run the whole update process:
} // sync tariff-files, download jsons,
} // download device controller
return;
}
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS));
setProgress(_CHECK_ISMAS_TRIGGER_SUCCESS);
////////////////////////////////////////////////////////////////////////////
@@ -473,8 +471,8 @@ bool Worker::updateTriggerSet() {
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::CHECK_ISMAS_TRIGGER));
QString triggerValue("NOT CHECKED YET");
static constexpr int const repeats = 15;
for (int repeat = 1; repeat <= repeats; ++repeat) {
for (int repeat = 1; repeat <= 100; ++repeat) {
if (repeat > 1) {
int const startMs = QTime::currentTime().msecsSinceStartOfDay();
@@ -482,12 +480,10 @@ bool Worker::updateTriggerSet() {
QString const &s = QString("elapsed: %1.%2s").arg(durationMs / 1000).arg(durationMs % 1000);
CONSOLE(QStringList(func) << s) << UPDATE_STEP::DEBUG;
} else {
QStringList lst = (QStringList(func) << QString("-> REPEAT=%1 (%2)").arg(repeat).arg(repeats-repeat));
// GUI(lst) << UPDATE_STEP::CHECK_ISMAS_TRIGGER;
CONSOLE(lst) << UPDATE_STEP::DEBUG;
CONSOLE(QStringList(func) << QString("-> REPEAT=%1").arg(repeat)) << UPDATE_STEP::DEBUG;
}
if ((repeat % 8) == 0) {
if ((repeat % 10) == 0) {
CONSOLE(QStringList(func) << "RESTART APISM") << UPDATE_STEP::DEBUG;
Command c("systemctl restart apism");
if (c.execute("/tmp")) {
@@ -577,7 +573,7 @@ bool Worker::updateTriggerSet() {
return m_ismasTriggerActive;
} else
if (QRegExp("\\s*").exactMatch(triggerValue)) { // check for whitespace
QStringList lst(QString("%1 empty update trigger (%2)").arg(repeat).arg(repeats-repeat));
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
@@ -659,31 +655,37 @@ bool Worker::filesToUpdate() {
// always execute contents of opkg_commands-file
m_filesToUpdate << "etc/psa_update/opkg_commands";
if (m_clone && m_alwaysDownloadConfig) {
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()) {
for (QStringList::size_type i=0; i<jsons.size(); ++i) {
m_filesToUpdate << QDir::cleanPath(QString("etc/psa_config/") + jsons.at(i));
}
m_filesToUpdate << jsons;
}
}
#endif
}
if (m_clone && m_alwaysDownloadDC) {
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/dc"));
QDir dir(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_update"));
if (dir.exists()) {
QStringList dc = dir.entryList(QStringList() << "dc2c.bin", QDir::Files,
QStringList dc = dir.entryList(QStringList() << "dc2c*.bin", QDir::Files,
QDir::SortFlag::Time | QDir::SortFlag::Reversed);
if (!dc.isEmpty()) {
m_filesToUpdate << QDir::cleanPath(QString("etc/dc/") + dc.first());
m_filesToUpdate << dc.first();
}
}
#endif
}
if (std::optional<QString> changes = m_gc.gitPull()) {
@@ -716,7 +718,8 @@ bool Worker::computeFilesToDownload() {
fName.contains("DC2C_cash", Qt::CaseInsensitive)) {
m_filesToDownload << fName; // download printer-config-files
} else {
if (fName.contains("dc2c.bin")) {
static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
if (fName.contains(version)) {
m_filesToDownload << fName; // download device controller
}
}
@@ -737,7 +740,7 @@ bool Worker::execOpkgCommands() {
if (f.open(QIODevice::ReadOnly)) {
QTextStream in(&f);
m_opkgCommands.clear();
QStringList opkgErrorLst;
bool executeOpkgCommandFailed = false;
while (!in.atEnd()) {
QString line = in.readLine();
static const QRegularExpression comment("^\\s*#.*$");
@@ -745,7 +748,7 @@ bool Worker::execOpkgCommands() {
// found opkg command
QString opkgCommand = line.trimmed();
if (!executeOpkgCommand(opkgCommand)) {
opkgErrorLst << opkgCommand;
executeOpkgCommandFailed = true;
} else {
QString cmd = "\n " + opkgCommand;
emit appendText(cmd);
@@ -799,15 +802,14 @@ bool Worker::execOpkgCommands() {
}
}
f.close();
if (opkgErrorLst.size() == 0) {
if (!executeOpkgCommandFailed) {
if (m_opkgCommands.size() > 0) {
m_displayIndex = 1;
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS));
GUI() << UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS;
setProgress(_EXEC_OPKG_COMMAND_SUCCESS);
}
} else {
m_displayIndex = 1;
ISMAS(opkgErrorLst) << (GUI(opkgErrorLst) << (CONSOLE() << UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE));
GUI() << UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE;
setProgress(_EXEC_OPKG_COMMAND_FAILURE);
return false;
@@ -830,24 +832,12 @@ bool Worker::downloadFilesToPSAHardware() {
if (computeFilesToDownload()) {
CONSOLE(m_filesToDownload) << UPDATE_STEP::FILES_TO_DOWNLOAD;
Update update(this,
QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr),
m_customerNrStr,
m_branchName,
m_pluginDir,
m_pluginName,
m_workingDirectory);
//m_update = new Update(this,
// QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr),
// m_customerNrStr, m_branchName, m_pluginDir,
// m_pluginName, m_workingDirectory);
if (update.doUpdate(m_displayIndex, m_filesToDownload)) {
// prepared for use: at the moment, the dc-library does not work
// as expected.
// static const QRegularExpression re("^.*\\.json$");
// return update.checkDownloadedJsonVersions(m_filesToDownload.filter(re));
return true;
}
return false;
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);

View File

@@ -557,10 +557,8 @@ private:
break;
case UPDATE_STEP::EXEC_OPKG_COMMAND_SUCCESS:
break;
case UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE: {
lst << instance->m_debugMsg;
Utils::printUpdateStatusMsg(debug, lst);
} break;
case UPDATE_STEP::EXEC_OPKG_COMMAND_FAILURE:
break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE:
break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS:
@@ -1127,9 +1125,6 @@ private:
break;
case UPDATE_STEP::CHECK_ISMAS_TRIGGER:
emit worker->appendText("\n" CHECK_UPDATE_TRIGGER_SET);
if (worker->m_guiMsg.size() > 0) {
emit worker->showStatusMessage(worker->m_guiMsg);
}
break;
case UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS:
break;