Compare commits

...

74 Commits

Author SHA1 Message Date
1ea1cdc3e6 set version to 1.5.7 after merge of pu/portrait 2025-02-19 12:08:17 +01:00
348fb15508
Ui: support portrait mode 2025-02-19 11:39:08 +01:00
061c57ef51 set verion to 1.5.6 2024-11-22 12:59:13 +01:00
e82417dde7 MainWindow::MainWindow():
Add status timer, to show proceeding update, so user does not exit
	application / restart machine.
2024-11-22 12:55:27 +01:00
1e271201c5 Set version to 1.5.5. 2024-11-21 09:15:33 +01:00
da66d75a45 getPSAInstalled():
call ptuPackagesVersion. Convert returned JSON-array into JsonObject
	to be appended to CMD_SENDVERSION.
2024-11-21 09:14:05 +01:00
7accabfa53 Add variables for handling ptu-package-versions and append corresponding data
to CMD_SENDVERSION.
2024-11-21 09:12:35 +01:00
201a1cbab9 privateUpdate():
Make sure opkg-commands re executed aunder certain error conditions:

	Failure of customerEnvironment(), filesToUpdate() or
	syncCustomerRepositoryAndFS().
2024-10-23 13:23:13 +02:00
9a9cce126a Minor: extended comment 2024-10-23 13:22:42 +02:00
da0fa54d28 gitPull():
Add important comment for the case that an remote host key change:
	'git pull' handles the issue itself, and continues to pull the repository
	using the ssh-key provided in the .keys/ directory.
2024-10-23 12:58:48 +02:00
1433c107b3 Remove right-justification in customer_id-name. Version: 1.5.3 2024-10-15 16:48:40 +02:00
8e0732cf95 Set version to 1.5.2. 2024-10-08 15:04:08 +02:00
8f6e1fdae7 clean up: remove .gz and .ipk files in /var/cache/opkg 2024-10-08 15:03:43 +02:00
0d00faf493 Remove hard coded (szeged) zone names 2024-07-23 09:28:54 +02:00
5beb235d92 Chop a trailing / of the repository url -> no clean path necessary 2024-07-17 14:50:32 +02:00
a4bb993217 Set version to 1.5.1 2024-07-17 14:06:18 +02:00
50357997c2 Do not use cleanPath() on an url-path 2024-07-17 14:04:53 +02:00
c02f0b08ed Set version to 1.5.0. 2024-06-28 13:01:24 +02:00
5da1eff41a Use repository-url="gitea@ptu-config.atb-comm.de:ATB/" 2024-06-28 12:58:13 +02:00
af89c9fbc1 Add SSH_GIT_COMMAND environment variable for pyu-config.atb-comm.de repository server. 2024-06-28 12:52:48 +02:00
fa7d1ba879 Allow empty lines in opkg_commands. 2024-06-28 12:50:30 +02:00
1dc7578645 Clean repository path from multiple slashes. 2024-06-28 12:49:53 +02:00
cd30cc91f0 Set version to 1.4.11. 2024-06-28 10:06:35 +02:00
6683b925aa Fix: remove hard-coded path to gitea repository (mimbach). 2024-06-28 10:03:10 +02:00
336d208906 Fix: never set the autoRequest-flag to false. 2024-06-26 13:27:39 +02:00
2da3c34d84 Set version to 1.4.10. 2024-06-26 13:26:55 +02:00
8f0a9112d6 Fix: do not set the autoRequest flag back to false. 2024-06-26 13:15:48 +02:00
25bf905a79 Use now new git-server: https://ptu-config.atb-comm.de/ATB 2024-06-14 13:36:34 +02:00
5d141b7234
Merge branch 'master' of git.mimbach49.de:GerhardHoffmann/ATBUpdateTool 2024-06-05 17:33:54 +02:00
ebb170123e Provide proto-binary 2024-06-05 10:10:21 +02:00
96bb70cfe9
Merge branch 'release_1.4.9' 2024-05-23 12:31:27 +02:00
8c1da92ff4
Make compile with yocto/bitbake 2024-05-23 12:29:07 +02:00
3e1a4ab09c Add comment for M0100 2024-05-17 12:32:53 +02:00
ee203e7672 doUpdate()/downloadJson(): send messages to ISMAS of the download
process of JSON files (DC2C_cash.json etc).
2024-05-17 12:29:02 +02:00
55c82eb509 Fix: send output to CONSOLE if directories are actually not equal. 2024-05-17 12:26:36 +02:00
f60cd9e4ef Again: improved ISMAS messages. 2024-05-17 12:26:03 +02:00
a9fb7a3630 Improve messages sent to ISMAS during update process. 2024-05-17 12:25:26 +02:00
db82f2af0d Fix: do not send a message to ISMAS about a check of the ISMAS
trigger (WAIT-button). For an automatic update this meant that
two messages have been visible in ISMAS which confused many users.
2024-05-17 12:22:38 +02:00
8b2e2d2086 For automatic updates send M0100, for user-triggered updates send U0002 = OK = Update aktivated. 2024-05-17 12:20:46 +02:00
5870f61395 Send UPDATE_SUCCEEDED (U0001 = 100%) only for user-triggered updates,
not for automatic ones.
2024-05-17 12:19:22 +02:00
aaa0f1e76c Minor: use correct string tor ISMAS message. 2024-05-17 12:18:11 +02:00
0d9a224977 Add M0100 message define. To be sent for automatic updates if not necessary. 2024-05-17 12:17:12 +02:00
d191020caa Configure new update-step values.
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS),
2024-05-17 08:47:10 +02:00
2b68242d04 Add new macro-values to improve output sent to ISMAS:
DOWNLOAD_CASH_FILE
DOWNLOAD_CASH_FILE_FAILURE
DOWNLOAD_CASH_FILE_SUCCESS
DOWNLOAD_DEVICE_FILE
DOWNLOAD_DEVICE_FILE_FAILURE
DOWNLOAD_DEVICE_FILE_SUCCESS
DOWNLOAD_JSON_FILE
DOWNLOAD_JSON_FILE_FAILURE
DOWNLOAD_JSON_FILE_SUCCESS

Adapt percent-counters to show progress of update process.
2024-05-17 08:43:37 +02:00
bd785e7df1 Minor: changes some debug text 2024-05-16 16:44:35 +02:00
f2534c7763 Fix: updateNewsToIsmas(): format TIMESTAMP with UTC-Offset suffix. 2024-05-16 10:36:58 +02:00
d2a6ae239d Set version to 1.4.9. 2024-05-15 15:06:54 +02:00
19273daa55 Do not install an own message-handler to prevent double-debug-output in
linux-journals.
2024-05-15 15:05:49 +02:00
ca67d1d159 Ignore RECORD-messages sent by APISM which do not have JSON format. 2024-05-15 15:04:51 +02:00
7c3e4ea497 Minor: remove some debug output. Error messages still intact. 2024-05-15 15:03:47 +02:00
f8897c2950 Implement Update::getInstalledJsonVersions(). 2024-05-15 15:02:53 +02:00
94a658ce8a Add some IMPORTANT comments about the format of JSON files to be downloaded. 2024-05-15 15:02:10 +02:00
9d9865e3c7 downloadJson(): continue update-process even when downloading of some JSON file fails. 2024-05-15 15:01:16 +02:00
a7d5a8f5cd Declaration of getInstalledJsonVersions() with default parameter. 2024-05-15 14:59:08 +02:00
cafd16a744 Read versions of JSON files installed on PSA (DC!).
If version is available, use as blob-value to be visible
in ISMAS.
2024-05-15 14:57:15 +02:00
5876c50a32 Make sure that SEND-LAST-VERSION is executed exactly once. 2024-05-15 14:56:41 +02:00
3b2200c0bf Make sure that SEND-LAST-VERSION is executed exactly once. 2024-05-15 14:55:55 +02:00
e8070a9e16 set port name 2024-05-14 16:39:09 +02:00
da10d6c2f6 make compile 2024-05-14 16:38:47 +02:00
c52b276722 first draft 2024-05-14 16:38:19 +02:00
e9cb421ac5 Add first draft 2024-05-14 16:37:45 +02:00
a3aef7594e Minor: add comment 2024-05-14 12:52:09 +02:00
afbcccf785 Minor: add comment about index shift: 4 -> 5 2024-05-14 12:51:32 +02:00
90e4e21391 System::getJsonFilesOnUsbStick(): return list of JSON files for configured
directory under mount path.
2024-05-14 12:49:28 +02:00
4536284f34 getUSBMountPath(): check for directory 'dirPathUnderMountPath' under mount path. 2024-05-14 12:48:19 +02:00
a3a4c09c7f checkForUSBStick(): look for etc/psa_config in mountpath-directory. 2024-05-14 12:46:38 +02:00
a5dd9af29a Add System::allowedJsonFiles to name default JSON file names. 2024-05-14 12:45:43 +02:00
5124e1cca6 Use return value of type std::optional<QString> for
checkForUSBStick() and getUSBMountPath().
Add getJsonFilesOnUsbStick().
2024-05-14 12:43:46 +02:00
fc75585de3 Parse psa-config-directory and psa-tariff-directory. 2024-05-14 12:40:32 +02:00
1964b08349 doUpdate(): use parameter 'usbStickDetected' to use the correct JSON
filenames.
2024-05-14 12:38:31 +02:00
c0d014644c Update (conf) JSON-Files using USB stick. When plugged in, look for
JSON-files in directory psa-config-directory and load them to the PSA.
Note: these files are overwritten during a usual ISMAS-update if not
checked in into the customer repository.
2024-05-14 12:35:18 +02:00
b24c50c572 Parse psa-config-directory and psa-tariff-directory settings. 2024-05-14 12:33:40 +02:00
bbdadc9063 Include psa_config_directory and psa_tariff_directory settings. 2024-05-14 12:32:26 +02:00
dc7f839d3f Include ATBUpdateTool.ini 2024-05-14 12:31:19 +02:00
31 changed files with 2330 additions and 258 deletions

View File

@ -1,9 +1,12 @@
[REPOSITORY_URL] [REPOSITORY_URL]
repository-url="https://git.mimbach49.de/GerhardHoffmann" repository-url="gitea@ptu-config.atb-comm.de:ATB/"
[DIRECTORIES] [DIRECTORIES]
plugin-directory="/usr/lib/" plugin-directory="/usr/lib/"
working-directory="/opt/app/tools/atbupdate/" working-directory="/opt/app/tools/atbupdate/"
psa-config-directory="etc/psa_config/"
psa-tariff-directory="etc/psa_tariff/"
[PLUGINS] [PLUGINS]
plugin-name="libCAslave.so" plugin-name="libCAslave.so"

View File

@ -16,6 +16,16 @@ GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}" EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
!contains(CONFIG, INCLUDEINTERFACES) {
INCLUDEINTERFACES=/opt/ptu5/opt/DCLibraries/include
}
INCLUDEPATH += \
plugins \
$${INCLUDEINTERFACES} \
$${_PRO_FILE_PWD_}/../UpdatePTUDevCtrl \
$${_PRO_FILE_PWD_}/../common/include
CONFIG += c++17 CONFIG += c++17
DEFINES+=APP_VERSION=\\\"$$VERSION\\\" DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
@ -68,20 +78,25 @@ contains( CONFIG, DesktopLinux ) {
SOURCES += \ SOURCES += \
main.cpp \ main.cpp \
mainwindow.cpp \ mainwindow.cpp \
sender_thread.cpp \ ../common/src/message_handler.cpp \
receiver_thread.cpp \ ../UpdatePTUDevCtrl/commandline_parser.cpp \
worker_thread.cpp \ update.cpp \
../common/src/message_handler.cpp dc_download.cpp \
../common/src/System.cpp
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
sender_thread.h \ ../common/include/message_handler.h \
receiver_thread.h \ ../UpdatePTUDevCtrl/commandline_parser.h \
worker_thread.h \ update.h \
../common/include/message_handler.h dc_download.h \
../common/include/System.h
OTHER_FILES += \ OTHER_FILES += \
ATBDownloadDCFirmware.ini ATBDownloadDCFirmware.ini \
../ATBUpdateTool.ini
FORMS += \ FORMS += \

View File

@ -0,0 +1,444 @@
#include "dc_download.h"
#include <DeviceController/interfaces.h>
#include <QFile>
#include <QDebug>
#include <QDateTime>
#include <QThread>
DcDownload::DcDownload(hwinf *hw)
: m_hw(hw)
, m_fileToDownload(m_hw->dcDownloadFileName()) {
// connect(this, &QThread::finished,
// dynamic_cast<QObject const *>(m_hw), &QThread::deleteLater);
}
DcDownload::~DcDownload() {
}
/*
///////////////////////////////////////////////////////////////////////////////
//
// USING THE DC BOOTLOADER
//
///////////////////////////////////////////////////////////////////////////////
1 : bl_reboot() // send to application, want DC2 to reset (in order to
// start the bootloader)
//
// NOTE: this function is NOT reliable !!! Sometimes it
// simply does not work, in which case bl_startBL,
// bl_checkBL and bl_isUp do not work as well.
// Alas, there is no feedback if bl_reboot worked!
//
// NOTE: this function can be called only once per
// minute, because once called again, the controller
// performs some self-checks consuming some time.
//
// NOTE: after a successful bl_reboot(), the device is
// waiting about 4 seconds in the bootloader. To stay in
// the bootloader, we have to send the command
// bl_startBL(), which is kind of a misnomer, as it
// should be bl_doNotLeaveBL().
//
2 : bl_startBL(): // send within 4s after DC power-on, otherwise
// bootloader is left.
//
// NOTE: a running bootloader is a MUST for the download
// process of a device controller firmware as it does
// the actual writing of the memory (the bl_reboot()
// from above erases the available memory).
//
3 : bl_check(): // send command to verify if bl is up
//
// NOTE: this command is kind of a request that we want
// to check if the bootloader is up. The device
// (actually the bootloader) responds with its version.
//
4 : bl_isUp(): // returns true if bl is up and running
//
// NOTE: we know what the bootloader version actually is
// as the bootloader does not change. By comparing the
// string received in the previous step with this known
// version string we know if the bootloader is up.
//
// NOTE FOR ALL PREVIOUS STEPS: execute them in their
// own slots each to be sure to receive any possible
// responds from the device.
//
5 : bl_sendAddress(blockNumber)
// send start address, nr of 64-byte block, start with 0
// will be sent only for following block-numbers:
// 0, 1024, 2048, 3072 and 4096, so basically every
// 64kByte.
// for other addresses nothing happens
6 : bl_wasSendingAddOK()
// return val: 0: no response by now
// 1: error
// 10: OK
7 : bl_sendDataBlock()
// send 64 byte from bin file
8 : bl_sendLastBlock()
// send this command after all data are transferred
9 : bl_wasSendingDataOK()
// return val: 0: no response by now
// 1: error
// 10: OK
10 : bl_stopBL() // leave bl and start (the new) application
//
// NOTE: this function MUST work under all conditions.
// Alas, there is no direct result for this command, so
// the only way of knowing it was successful is to ask
// the device if the bootloader is still running.
// There is no problem to repeat this command until the
// bootloader is really not running anymore.
*/
void DcDownload::doDownload() {
#if 0
void DcDownload::run() {
// download thread running in ca-master sends the dc-file down to firmware
// TODO: send the json files as well
m_hw->dcDownloadRequestAck();
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): DOWNLOAD THREAD STARTED:";
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< " DcDownload::run(): Filename:" << m_hw->dcDownloadFileName();
QDateTime const start = QDateTime::currentDateTime();
#if 1
QFile fn(m_hw->dcDownloadFileName());
if (!fn.exists()) {
// output via CONSOLE() etc
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< " DcDownload::run(): Filename:" << m_hw->dcDownloadFileName() << "DOES NOT EXIST";;
} else {
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): DC-CONTROLLER SW-VERSION BEFORE"
<< m_hw->dc_getSWversion();
// load binary device controller file into memory
QByteArray ba = loadBinaryDCFile(m_hw->dcDownloadFileName());
if (ba.size() > 0) {
uint16_t const totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1;
m_hw->dcDownloadSetTotalBlockNumber(totalBlocks);
// fill last block of data to be sent with 0xFF
ba = ba.leftJustified(totalBlocks*64, (char)(0xFF));
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): TOTAL NUMBER OF BYTES TO SEND TO DC" << ba.size();
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): TOTAL NUMBER OF BLOCKS" << totalBlocks;
m_hw->dc_autoRequest(true); // turn auto-request setting on
m_hw->request_DC2_HWversion();
m_hw->request_DC2_SWversion();
QThread::sleep(1);
// m_hw->dc_autoRequest(false); // turn auto-request setting on
resetDeviceController();
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): RESET DEVICE-CONTROLLER";
if (startBootloader()) {
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): STARTED BOOT-LOADER";
m_hw->dc_autoRequest(false);// turn auto-request setting off for
// download of binary dc
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): TOTAL NUMBER OF FIRMWARE BLOCKS" << totalBlocks;
int currentBlock = 0; // download of binary dc
DownloadResult res = DownloadResult::OK;
while (res != DownloadResult::ERROR && currentBlock < totalBlocks) {
if ((res = sendNextAddress(currentBlock)) != DownloadResult::ERROR) {
if ((res = sendNextDataBlock(ba, currentBlock)) != DownloadResult::ERROR) {
m_hw->dcDownloadSetCurrentBlockNumber(currentBlock);
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): currentBlockNumber ..." << currentBlock;
currentBlock += 1;
}
}
}
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< QString("DcDownload::run(): last 64-byte block %1").arg(currentBlock);
int const rest = ba.size() % 64;
int const offset = ba.size() - rest;
char const *startAddress = ba.constData() + offset;
if (rest > 0) {
// SHOULD NEVER HAPPEN !!!
uint8_t local[66];
memset(local, 0xFF, sizeof(local));
memcpy(local, startAddress, rest);
qCritical() << "DcDownload::run(): ERROR SEND REMAINING" << rest << "BYTES";
m_hw->bl_sendDataBlock(64, local);
} else {
m_hw->bl_sendLastBlock();
m_hw->dcDownloadSetCurrentBlockNumber(currentBlock);
qCritical() << "DcDownload::run(): currentBlockNumber" << currentBlock;
// QThread::msleep(250);
}
qCritical() << "DcDownload::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK());
stopBootloader(); // stop bootloader several times: if it
QThread::sleep(1); // is not stopped, then the PSA has to be
}
// restarted manually (!!!)
stopBootloader();
QThread::sleep(1);
}
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): STOPPED BOOT-LOADER";
stopBootloader(); // there is no harm in stopping the bootloader even
// if it was not started at all
m_hw->dc_autoRequest(true);
}
#else // test
// load binary device controller file into memory
QByteArray ba = loadBinaryDCFile(m_hw->dcDownloadFileName());
if (ba.size() > 0) {
uint16_t const totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1;
m_hw->dcDownloadSetTotalBlockNumber(totalBlocks);
// fill last block of data to be sent with 0xFF
ba = ba.leftJustified(totalBlocks*64, (char)(0xFF));
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): TOTAL NUMBER OF BYTES TO SEND TO DC" << ba.size();
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): TOTAL NUMBER OF BLOCKS" << totalBlocks;
m_hw->dc_autoRequest(true); // turn auto-request setting on
m_hw->request_DC2_HWversion();
m_hw->request_DC2_SWversion();
QThread::sleep(1);
resetDeviceController();
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): RESET DEVICE-CONTROLLER";
QThread::sleep(1);
if (startBootloader()) {
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): STARTED BOOT-LOADER";
m_hw->dc_autoRequest(false);// turn auto-request setting off for
// download of binary dc
for (uint16_t currentBlock = 0; currentBlock <= totalBlocks; ++currentBlock) {
m_hw->dcDownloadSetCurrentBlockNumber(currentBlock);
qCritical() << "DcDownload::run(): currentBlockNumber" << currentBlock;
QThread::msleep(250);
}
m_hw->dc_autoRequest(true); // turn auto-request setting on again
}
stopBootloader(); // there is no harm in stopping the bootloader even
// if it was not started at all
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "DcDownload::run(): STOPPED BOOT-LOADER";
}
#endif
m_hw->dcDownloadSetRunning(false);
m_hw->dcDownloadSetFinished(true);
QDateTime const end = QDateTime::currentDateTime();
quint64 secs = start.secsTo(end);
QString runtime;
if (secs % 60) {
runtime = QString("%1min %2s").arg(secs / 60).arg(secs % 60);
} else {
runtime = QString("%1min").arg((secs / 60) + 1);
}
qCritical() << end.time().toString(Qt::ISODateWithMs)
<< QString("DOWNLOAD THREAD FINISHED (RUNTIME %1)")
.arg(runtime);
// the object deletes itself ! This is the last line in run().
// Never touch the object after this statement
// m_hw->dcDcDownloadFinalize(this);
#endif
}
DcDownload::DownloadResult DcDownload::sendStatus(int ret) const {
switch (ret) { // return values of dc are:
case 0: // 0: no answer by now
return DownloadResult::NOP; // 1: error
case 10: // 10: success
return DownloadResult::OK;
default:;
}
return DownloadResult::ERROR;
}
DcDownload::DownloadResult
DcDownload::sendNextAddress(int bNum) const {
// sends address only if blockNumber is one of 0, 1024, 2048, 3072, 4096
int noAnswerCount = 0;
int errorCount = 0;
if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) {
while (noAnswerCount <= 250) {
m_hw->bl_sendAddress(bNum);
QThread::msleep(100);
DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK());
if (res != DownloadResult::NOP) {
if (res == DownloadResult::ERROR) {
if (++errorCount >= 10) {
qCritical() << "addr-block" << bNum << "...FAILED";
return res;
}
} else { // res == DownloadResult::OK
// qInfo() << "addr-block" << bNum << "...OK";
// TODO: hier ins shared-mem schreiben
return res;
}
} else {
noAnswerCount += 1; // no answer by now
}
}
// wait max. about 3 seconds
return DownloadResult::TIMEOUT;
}
// blockNumber is not one of 0, 1024, 2048, 3072, 4096 -> do nothing
return DownloadResult::NOP;
}
DcDownload::DownloadResult
DcDownload::sendNextDataBlock(QByteArray const &binary, int bNum) const {
uint8_t local[66];
int const bAddr = bNum * 64;
int noAnswerCount = 0;
int errorCount = 0;
memcpy(local, binary.constData() + bAddr, 64);
local[64] = local[65] = 0x00;
while (noAnswerCount <= 250) {
m_hw->bl_sendDataBlock(64, local);
QThread::msleep(10);
DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK());
if (res != DownloadResult::NOP) {
if (res == DownloadResult::ERROR) {
if (++errorCount >= 10) {
qCritical() << "data for block" << bNum << "...FAILED";
return res;
}
} else {
// qInfo() << "data for block" << bNum << "OK";
// TODO: hier ins shared mem schreiben
return res;
}
} else {
noAnswerCount += 1; // no answer by now
}
}
// wait max. about 3 seconds
return DownloadResult::TIMEOUT;
}
bool DcDownload::startBootloader() const {
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "starting bootloader...";
int nTry = 5;
while (--nTry >= 0) {
m_hw->bl_startBL();
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs) << "bl_startBL() ..." << nTry;
QThread::msleep(500);
m_hw->bl_checkBL();
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs) << "bl_checkBL() ..." << nTry;
QThread::msleep(500);
if (m_hw->bl_isUp()) {
qInfo() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs) << "bootloader... isUP" << nTry;
return true;
} else {
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "bootloader not up (" << nTry << ")";
}
}
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "starting bootloader FAILED";
return false;
}
bool DcDownload::stopBootloader() const {
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "stopping bootloader...";
int nTry = 5;
while (--nTry >= 0) {
m_hw->bl_stopBL();
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "bl_stopBL() ...";
QThread::msleep(500);
m_hw->bl_checkBL();
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs) << "bl_checkBL() ..." << nTry;
if (!m_hw->bl_isUp()) {
qInfo() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "stopping bootloader OK";
return true;
}
}
qCritical() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "stopping bootloader FAILED";
return false;
}
bool DcDownload::resetDeviceController() const {
qDebug() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "resetting device controller...";
m_hw->bl_rebootDC();
// wait maximally 3 seconds, before starting bootloader
QThread::sleep(1);
qInfo() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "resetting device controller...OK";
return true;
}
QByteArray DcDownload::loadBinaryDCFile(QString filename) const {
qInfo() << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
<< "loading dc binary" << filename << "...";
QFile file(filename); // closed in destructor call
if (!file.exists()) {
qCritical() << file.fileName() << "does not exist";
return QByteArray();
}
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "cannot open file" << file.fileName();
return QByteArray();
}
qInfo() << "loading dc binary" << filename << "...OK";
return file.readAll();
}

View File

@ -0,0 +1,32 @@
#ifndef DC_DOWNLOAD_H_INCLUDED
#define DC_DOWNLOAD_H_INCLUDED
#include <QString>
#include <QByteArray>
class hwinf;
class DcDownload {
public:
enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
DcDownload(hwinf *hw);
~DcDownload();
void doDownload();
private:
DownloadResult sendStatus(int ret) const;
DownloadResult sendNextAddress(int bNum) const;
DownloadResult sendNextDataBlock(QByteArray const &binary, int bNum) const;
bool startBootloader() const;
bool stopBootloader() const;
QByteArray loadBinaryDCFile(QString dcFileName) const;
bool resetDeviceController() const;
DownloadResult dcDownloadBinary(QByteArray const &b) const;
hwinf *m_hw;
QString m_fileToDownload;
};
#endif // DOWNLOAD_THREAD_H_INCLUDED

View File

@ -1,13 +1,25 @@
#include <QtGlobal> #include <QtGlobal>
#include <QCoreApplication> #include <QCoreApplication>
#include <QApplication> #include <QApplication>
#include <QByteArray>
#include <QProcess>
#include <QCommandLineParser>
#include <QStandardPaths>
#include <QSettings>
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QTimer>
#include <QFileInfo>
#include <QThread> #include <QThread>
#include "../common/include/message_handler.h" #include "message_handler.h"
#include "commandline_parser.h"
#include "utils.h"
#include "update.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "System.h"
#include <DeviceController/interfaces.h>
#ifdef __linux__ #ifdef __linux__
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
@ -19,6 +31,20 @@
#define SERIAL_PORT "ttyUSB0" #define SERIAL_PORT "ttyUSB0"
#endif #endif
int 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;
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
QByteArray const value = qgetenv("LC_ALL"); QByteArray const value = qgetenv("LC_ALL");
if (value != "C") { if (value != "C") {
@ -29,7 +55,7 @@ int main(int argc, char **argv) {
openlog("ATB-UPDATE-DC-FIRMWARE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER); openlog("ATB-UPDATE-DC-FIRMWARE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
QApplication a(argc, argv); QApplication a(argc, argv);
QApplication::setApplicationName("ATBUpdateTool"); QApplication::setApplicationName("ATBDownloadDCFirmware");
QApplication::setApplicationVersion(APP_VERSION); QApplication::setApplicationVersion(APP_VERSION);
if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
@ -37,6 +63,61 @@ int main(int argc, char **argv) {
setDebugLevel(LOG_NOTICE); setDebugLevel(LOG_NOTICE);
} }
CommandLineParser parser;
parser.process(a);
parser.readSettings();
QString repositoryUrl = parser.repositoryUrl();
QString plugInDir = parser.plugInDir();
QString plugInName = parser.plugInName();
QString workingDir = parser.workingDir();
QString psaConfigDir = parser.psaConfigDir();
QString psaTariffDir = parser.psaTariffDir();
QString iniFileName = parser.iniFileName();
bool const dryRun = parser.dryRun();
bool const noUpdatePsaHardware = parser.noUpdatePsaHardware();
bool const showYoctoVersion = parser.yoctoVersion();
bool const showYoctoInstallStatus = parser.yoctoInstallStatus();
bool const showExtendedVersion = parser.extendedVersion();
bool const alwaysDownloadConfig = parser.alwaysDownloadConfig();
bool const alwaysDownloadDC = parser.alwaysDownloadDC();
QString const rtPath = QCoreApplication::applicationDirPath();
int const machineNr = read1stLineOfFile("/mnt/system_data/machine_nr");
int const customerNr = read1stLineOfFile("/mnt/system_data/cust_nr");
int const zoneNr = read1stLineOfFile("/mnt/system_data/zone_nr");
QString const branchName = (zoneNr != 0)
? QString("zg1/zone%1").arg(zoneNr) : "master";
qInfo() << "pwd ......................" << rtPath;
qInfo() << "repositoryUrl ............" << repositoryUrl;
qInfo() << "plugInDir ................" << plugInDir;
qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir;
qInfo() << "psaConfigDir ............." << psaConfigDir;
qInfo() << "psaTariffDir ............." << psaTariffDir;
qInfo() << "dryRun ..................." << dryRun;
qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware;
qInfo() << "alwaysDownloadConfig ....." << alwaysDownloadConfig;
qInfo() << "alwaysDownloadDC ........." << alwaysDownloadDC;
qInfo() << "showYoctoVersion ........." << showYoctoVersion;
qInfo() << "showYoctoInstallStatus ..." << showYoctoInstallStatus;
qInfo() << "showExtendedVersion ......" << showExtendedVersion;
qInfo() << "iniFileName .............." << iniFileName;
qInfo() << "extended-version ........." << APP_EXTENDED_VERSION;
qInfo() << "machineNr ................" << machineNr;
qInfo() << "customerNr ..............." << customerNr;
qInfo() << "zoneNr ..................." << zoneNr;
if (showExtendedVersion) {
printf(APP_EXTENDED_VERSION"\n");
return 0;
}
QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr));
QStringList filesToUpdate;
QThread::currentThread()->setObjectName("main thread"); QThread::currentThread()->setObjectName("main thread");
qInfo() << "Main thread" << QThread::currentThreadId(); qInfo() << "Main thread" << QThread::currentThreadId();
@ -45,9 +126,10 @@ int main(int argc, char **argv) {
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint); mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
// mw.showFullScreen(); // mw.showFullScreen();
qCritical() << "SHOW"; // qCritical() << "SHOW";
mw.show(); // mw.show();
return a.exec(); return 0;
// return a.exec();
} }

View File

@ -7,6 +7,11 @@
#include <QScrollBar> #include <QScrollBar>
#include <QEvent> #include <QEvent>
#ifdef PTU5
#define SERIAL_PORT "ttymxc2"
#else
#define SERIAL_PORT "ttyUSB0"
#endif
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -79,7 +84,7 @@ MainWindow::~MainWindow() {
bool MainWindow::openSerialPort() { bool MainWindow::openSerialPort() {
// const SettingsDialog::Settings p = m_settings->settings(); // const SettingsDialog::Settings p = m_settings->settings();
m_serial->setPortName(""); m_serial->setPortName(SERIAL_PORT);
m_serial->setBaudRate(QSerialPort::Baud115200); m_serial->setBaudRate(QSerialPort::Baud115200);
m_serial->setDataBits(QSerialPort::DataBits::Data8); m_serial->setDataBits(QSerialPort::DataBits::Data8);
m_serial->setParity(QSerialPort::Parity::NoParity); m_serial->setParity(QSerialPort::Parity::NoParity);

View File

@ -0,0 +1,438 @@
#include "update.h"
#include <QCoreApplication>
#include <QFile>
#include <QTemporaryFile>
#include <QDebug>
#include <QTextStream>
#include <QRegularExpression>
#include <QRegExp>
#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
#include "unistd.h"
#endif
#include <DeviceController/interfaces.h>
#include <QSharedMemory>
#include <QScopedPointer>
#include <QDir>
#include <QThread>
#include <QDateTime>
#include <QPluginLoader>
#include <QMap>
#define UPDATE_OPKG (1)
#define UPDATE_DC (0)
static const QMap<QString, int> baudrateMap = {
{"1200" , 0}, {"9600" , 1}, {"19200" , 2}, {"38400" , 3},
{"57600" , 4}, {"115200" , 5}
};
QPluginLoader Update::pluginLoader;
hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
hwinf *hw = nullptr;
if (plugInDir.exists()) {
QString pluginLibName(fname);
pluginLibName = plugInDir.absoluteFilePath(pluginLibName);
QFileInfo info(pluginLibName);
if (info.exists()) {
pluginLibName = plugInDir.absoluteFilePath(pluginLibName);
pluginLoader.setFileName(pluginLibName);
// static QPluginLoader pluginLoader(pluginLibName);
if (!pluginLoader.load()) {
qCritical() << "in directory" << plugInDir.absolutePath();
qCritical() << "cannot load plugin" << pluginLoader.fileName();
qCritical() << pluginLoader.errorString();
return nullptr;
}
qCritical() << "loadDCPlugin() plugin directory:" << plugInDir.absolutePath();
qCritical() << "loadDCPlugin() plugin file name:" << pluginLoader.fileName();
if (!pluginLoader.isLoaded()) {
qCritical() << pluginLoader.errorString();
return nullptr;
}
QObject *plugin = pluginLoader.instance();
if (!plugin) {
qCritical() << "cannot start instance";
return nullptr;
}
if (! (hw = qobject_cast<hwinf *>(plugin))) {
qCritical() << "cannot cast plugin" << plugin << "to hwinf";
return nullptr;
}
} else {
qCritical() << pluginLibName << "does not exist";
return nullptr;
}
} else {
qCritical() << "plugins directory" << plugInDir.absolutePath()
<< "does not exist";
return nullptr;
}
return hw;
}
bool Update::unloadDCPlugin() {
if (pluginLoader.unload()) {
qCritical() << "unloaded plugin" << pluginLoader.fileName();
// Note: will re-instantiate the library !
// QObject *rootObject = pluginLoader.instance();
// if (rootObject) {
// qCritical() << "reloaded plugin: root object again available";
// return false;
// }
// qCritical()unloaded plugin: root object gone";
return true;
}
return false;
}
class hwapi;
Update::Update(QString customerRepository,
QString customerNrStr,
QString branchName,
QString plugInDir,
QString pluginName,
QString workingDir,
bool dryRun,
QObject *parent,
char const *serialInterface,
char const *baudrate)
: QObject(parent)
, m_hw(loadDCPlugin(QDir(plugInDir), pluginName))
, m_serialInterface(serialInterface)
, m_baudrate(baudrate)
, m_customerRepository(customerRepository)
, m_customerNrStr(customerNrStr)
, m_branchName(branchName)
, m_pluginName(pluginName)
, m_workingDir(workingDir)
, m_dryRun(dryRun)
, m_sys_areDCdataValid(false) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_hw == nullptr -> ca-slave plugin loaded ???";
} else {
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);
}
qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_sys_areDCDataValid ..."
<< m_sys_areDCdataValid;
}
}
Update::~Update() {
unloadDCPlugin();
}
bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return 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() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
return false;
}
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
bool res = false;
QList<QString>::const_iterator it;
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed())
: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed());
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))) {
qCritical() <<
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
.arg(fToWorkOn)
.arg(templateIdx);
}
}
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
if ((res = updateCashConf(fToWorkOn))) {
qCritical() << QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn);
}
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
if ((res = updateConfig(fToWorkOn))) {
qCritical() << QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn);
}
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
if ((res = updateDeviceConf(fToWorkOn))) {
qCritical() << QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn);
}
} else {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false;
}
}
return res;
}
bool Update::checkJsonVersions(QStringList const& jsonFileNames) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return 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() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
return false;
}
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) {
uint8_t jsonNr = 0;
QString const &fName = jsonFileNames[i];
// send one request for every single version
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 6=printer template 1 ..... 36= template 32
if (fName.endsWith("conf.json")) {
jsonNr = 1;
} else
if (fName.endsWith("device.json")) {
jsonNr = 2;
} else
if (fName.endsWith("cash.json")) {
jsonNr = 3;
} else {
QRegularExpressionMatch match;
static const QRegularExpression re("^(.*print)([0-3][0-9])\\.json\\s*$");
int idx = fName.indexOf(re, 0, &match);
if (idx != -1) {
QString captured = match.captured(match.lastCapturedIndex());
bool ok = false;
int n = captured.toInt(&ok);
if (ok) {
// note: use 5 (instead of 4 -> index has been shifted)
jsonNr = n + 5;
}
}
}
if (jsonNr != 0) {
// send one request for every single version
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 5=printer template 1 ..... 36= template 32
m_hw->sys_requestJsonVersions(jsonNr);
QThread::msleep(500);
char buf[64];
memset(buf, 0x00, sizeof(buf));
m_hw->sys_getJsonVersions(jsonNr, buf);
buf[16] = '\0'; // the DC only handles 16 bytes
static const QByteArray cb(16, (char)0xff);
QString const installedVersion(QString::fromStdString(buf));
QString const fileVersion = getFileVersion(jsonFileNames[i]);
QFileInfo fi(jsonFileNames[i]);
qCritical() << endl;
qCritical() << " json request nr:" << jsonNr;
if (installedVersion == fileVersion) {
qCritical() << " json file:" << fi.fileName();
qCritical() << " installed version in DC:" << installedVersion;
} else
if (cb == QByteArray(buf) && fileVersion == "") {
qCritical() << "unknown json file (repo and DC):" << fi.fileName();
} else {
qCritical() << " json file:" << fi.fileName();
qCritical() << " installed version in DC:" << installedVersion;
qCritical() << " file version in repository:" << fileVersion;
}
} else {
qCritical() << "CANNOT FIND JSON-NR FOR" << fName;
}
}
return false;
}
QString Update::getFileVersion(QString const& jsonFileName) {
// "version":"15.10.2023 14:55 02.00.06",
static const QRegularExpression re("^.*(\\\"[Vv]ersion\\\":)([\\s\\\"]{0,})([^,\\\"]{0,}).*$");
QString fileVersion("");
QFile inputFile(QDir::cleanPath(m_customerRepository + QDir::separator() + jsonFileName));
if (inputFile.exists()) {
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) {
int const lastCaptured = match.lastCapturedIndex();
// the dc only sends 16 Byte
fileVersion = match.captured(lastCaptured);
fileVersion.truncate(16);
break;
}
}
inputFile.close();
}
} else {
// qCritical() << "ERROR" << inputFile.fileName() << "does not exist";
}
return fileVersion;
}
bool Update::downloadJson(enum FileTypeJson type,
int templateIdx,
QString jsFileToSendToDC) const {
m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag
qDebug() << "SET AUTO-REQUEST=TRUE";
QThread::sleep(1); // make sure the auto-request flag is acknowledged
QStringList lst;
bool ready = false;
int nTry = 25;
while ((ready = m_hw->sys_ready4sending()) == false) {
QThread::msleep(200);
if (--nTry <= 0) {
qCritical() << "SYS NOT READY FOR SENDING AFTER 5 SECONDS";
break;
}
}
bool ret = false;
QString msg;
lst.clear();
if (ready) {
QFile file(jsFileToSendToDC);
QFileInfo fi(jsFileToSendToDC); // max. size of template file is 800 bytes
if (file.exists()) {
if (file.open(QIODevice::ReadOnly)) {
if (fi.size() > 0 && fi.size() <= 800) {
QByteArray ba = file.readAll();
// kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
// nrOfTemplate=1...32 if kindOfFile==6
// content = content of the Json file, max 800byte ascii signs
if (m_hw->sys_sendJsonFileToDc((uint8_t)(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);
// testing
m_hw->request_ReadbackMachineID();
QThread::msleep(500);
uint8_t data[64];
memset(data, 0x00, sizeof(data));
uint8_t length = 0;
m_hw->readback_machineIDdata(&length, data);
QThread::msleep(500);
QByteArray ba((const char*)data, length);
qCritical() << length << "MACHINE ID =" << ba.toHex(':');
*/
ret = true;
} else {
qCritical() << QString("ERROR SEND JSON-FILE %1 TO DC").arg(file.fileName());
}
} else {
qCritical() << QString("SIZE OF %1 TOO BIG (%2 BYTES)").arg(jsFileToSendToDC).arg(fi.size());
}
} else {
qCritical() << QString("CAN NOT OPEN ") + jsFileToSendToDC + " FOR READING";
}
} else {
qCritical() << (QString(jsFileToSendToDC) + " DOES NOT EXIST");
}
}
m_hw->dc_autoRequest(false);
qDebug() << "SET AUTO-REQUEST=FALSE";
QThread::sleep(1); // make sure the auto-request flag is acknowledged
return ret;
}
bool Update::updatePrinterTemplate(int templateIdx, QString jsFile) const {
return downloadJson(FileTypeJson::PRINTER, templateIdx, jsFile);
}
bool Update::updateConfig(QString jsFile) {
return downloadJson(FileTypeJson::CONFIG, 0, jsFile);
}
bool Update::updateCashConf(QString jsFile) {
return downloadJson(FileTypeJson::CASH, 0, jsFile);
}
bool Update::updateDeviceConf(QString jsFile) {
return downloadJson(FileTypeJson::DEVICE, 0, jsFile);
}

148
DownloadDCFirmware/update.h Normal file
View File

@ -0,0 +1,148 @@
#ifndef UPDATE_H_INCLUDED
#define UPDATE_H_INCLUDED
#include <QObject>
#include <QString>
#include <QFile>
#include <QDir>
#include <QByteArray>
#include <QProcess>
#include <QPluginLoader>
#include <initializer_list>
#include <DeviceController/interfaces.h>
#ifdef PTU5
#define SERIAL_PORT "ttymxc2"
#else
#define SERIAL_PORT "ttyUSB0"
#endif
class Update : public QObject {
Q_OBJECT
hwinf *m_hw = nullptr;
char const *m_serialInterface;
char const *m_baudrate;
QString m_customerRepository;
QString m_customerNrStr;
QString m_branchName;
QString m_pluginName;
QString m_workingDir;
bool m_maintenanceMode;
bool m_dryRun;
bool m_sys_areDCdataValid;
static QPluginLoader pluginLoader;
public:
enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
enum class FileTypeJson {CONFIG=1, DEVICE=2, CASH=3, SERIAL=4, TIME=5, PRINTER=6};
static hwinf *loadDCPlugin(QDir const &plugInDir, QString const &fn);
static bool unloadDCPlugin();
static QStringList split(QString line, QChar sep = ',');
explicit Update(QString customerRepository,
QString customerNrStr,
QString branchName,
QString plugInDir,
QString pluginName,
QString workingDir,
bool dryRun = false,
QObject *parent = nullptr,
char const *serialInterface = SERIAL_PORT,
char const *baudrate = "115200");
virtual ~Update() override;
bool doUpdate(QStringList const &jsonFilesToDownload, bool usbStickDetected = false);
bool updatePrinterTemplate(int templateIdx, QString fname) const;
bool updateConfig(QString jsFileToSendToDC);
bool updateCashConf(QString jsFileToSendToDC);
bool updateDeviceConf(QString jsFileToSendToDC);
bool downloadJson(enum FileTypeJson type, int templateIdx,
QString jsFileToSendToDC) const;
QString getFileVersion(QString const& jsonFileName);
bool checkJsonVersions(QStringList const& jsonFileNames =
QStringList(
QList(
std::initializer_list<QString>{
QString("etc/psa_config/DC2C_conf.json"),
QString("etc/psa_config/DC2C_cash.json"),
QString("etc/psa_config/DC2C_device.json"),
QString("etc/psa_config/DC2C_print01.json"),
QString("etc/psa_config/DC2C_print02.json"),
QString("etc/psa_config/DC2C_print03.json"),
QString("etc/psa_config/DC2C_print04.json"),
QString("etc/psa_config/DC2C_print05.json"),
QString("etc/psa_config/DC2C_print06.json"),
QString("etc/psa_config/DC2C_print07.json"),
QString("etc/psa_config/DC2C_print08.json"),
QString("etc/psa_config/DC2C_print09.json"),
QString("etc/psa_config/DC2C_print10.json"),
QString("etc/psa_config/DC2C_print11.json"),
QString("etc/psa_config/DC2C_print12.json"),
QString("etc/psa_config/DC2C_print13.json"),
QString("etc/psa_config/DC2C_print14.json"),
QString("etc/psa_config/DC2C_print15.json"),
QString("etc/psa_config/DC2C_print16.json"),
QString("etc/psa_config/DC2C_print17.json"),
QString("etc/psa_config/DC2C_print18.json"),
QString("etc/psa_config/DC2C_print19.json"),
QString("etc/psa_config/DC2C_print20.json"),
QString("etc/psa_config/DC2C_print21.json"),
QString("etc/psa_config/DC2C_print22.json"),
QString("etc/psa_config/DC2C_print23.json"),
QString("etc/psa_config/DC2C_print24.json"),
QString("etc/psa_config/DC2C_print25.json"),
QString("etc/psa_config/DC2C_print26.json"),
QString("etc/psa_config/DC2C_print27.json"),
QString("etc/psa_config/DC2C_print28.json"),
QString("etc/psa_config/DC2C_print29.json"),
QString("etc/psa_config/DC2C_print30.json"),
QString("etc/psa_config/DC2C_print31.json"),
QString("etc/psa_config/DC2C_print32.json")})));
/*
bool checkDownloadedJsonVersions(QStringList const& jsonFileNames);
hwinf *hw() { return m_hw; }
hwinf const *hw() const { return m_hw; }
//QString customerId() { return m_customerId; }
//QString const customerId() const { return m_customerId; }
QString branchName() { return m_branchName; }
QString const branchName() const { return m_branchName; }
//QString repositoryPath() { return m_repositoryPath; }
//QString const repositoryPath() const { return m_repositoryPath; }
private:
static QString jsonType(enum FileTypeJson type);
bool openSerial(int br, QString baudrate, QString comPort) const;
void closeSerial() const;
bool isSerialOpen() const;
bool resetDeviceController() const;
QByteArray loadBinaryDCFile(QString filename) const;
bool downloadBinaryToDC(QString const &bFile) const;
bool updateBinary(QString const &fileToSendToDC);
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

@ -90,7 +90,8 @@ HEADERS += \
../common/include/System.h ../common/include/System.h
OTHER_FILES += \ OTHER_FILES += \
ATBDownloadDCJsonFiles.ini ATBDownloadDCJsonFiles.ini \
../ATBUpdateTool.ini
########################################################################################## ##########################################################################################

View File

@ -15,6 +15,7 @@
#include "commandline_parser.h" #include "commandline_parser.h"
#include "utils.h" #include "utils.h"
#include "update.h" #include "update.h"
#include "System.h"
#include <DeviceController/interfaces.h> #include <DeviceController/interfaces.h>
@ -68,6 +69,8 @@ int main(int argc, char **argv) {
QString plugInDir = parser.plugInDir(); QString plugInDir = parser.plugInDir();
QString plugInName = parser.plugInName(); QString plugInName = parser.plugInName();
QString workingDir = parser.workingDir(); QString workingDir = parser.workingDir();
QString psaConfigDir = parser.psaConfigDir();
QString psaTariffDir = parser.psaTariffDir();
QString iniFileName = parser.iniFileName(); QString iniFileName = parser.iniFileName();
bool const dryRun = parser.dryRun(); bool const dryRun = parser.dryRun();
bool const noUpdatePsaHardware = parser.noUpdatePsaHardware(); bool const noUpdatePsaHardware = parser.noUpdatePsaHardware();
@ -90,6 +93,8 @@ int main(int argc, char **argv) {
qInfo() << "plugInDir ................" << plugInDir; qInfo() << "plugInDir ................" << plugInDir;
qInfo() << "plugInName ..............." << plugInName; qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir; qInfo() << "workingDir ..............." << workingDir;
qInfo() << "psaConfigDir ............." << psaConfigDir;
qInfo() << "psaTariffDir ............." << psaTariffDir;
qInfo() << "dryRun ..................." << dryRun; qInfo() << "dryRun ..................." << dryRun;
qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware; qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware;
qInfo() << "alwaysDownloadConfig ....." << alwaysDownloadConfig; qInfo() << "alwaysDownloadConfig ....." << alwaysDownloadConfig;
@ -108,15 +113,17 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
QString const customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr)); QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr));
qCritical() << "Using customer repository" << customerRepo;
// always execute contents of opkg_commands-file
QStringList filesToUpdate; QStringList filesToUpdate;
QDir dir(QDir::cleanPath(customerRepo + QDir::separator() + "etc/psa_config")); // etc/psa_config: located under mount-path
std::optional<QString> mountPath = System::checkForUSBStick(psaConfigDir);
if (mountPath.has_value()) {
filesToUpdate = System::getJsonFilesOnUsbStick(mountPath.value());
} else {
qCritical() << "Using customer repository" << customerRepo;
QDir dir(QDir::cleanPath(customerRepo + QDir::separator() + "etc/psa_config"));
if (dir.exists()) { if (dir.exists()) {
QStringList jsons = dir.entryList(QStringList() << "DC2C*.json", QDir::Files); QStringList jsons = dir.entryList(QStringList() << "DC2C*.json", QDir::Files);
if (!jsons.isEmpty()) { if (!jsons.isEmpty()) {
@ -128,8 +135,9 @@ int main(int argc, char **argv) {
qCritical() << "DIRECTORY" << dir << "DOES NOT EXIST"; qCritical() << "DIRECTORY" << dir << "DOES NOT EXIST";
return -1; return -1;
} }
}
qCritical() << "JSON FILES TO UPDATE" << filesToUpdate; // qCritical() << "JSON FILES TO UPDATE" << filesToUpdate;
Update update(customerRepo, Update update(customerRepo,
QString::number(customerNr), QString::number(customerNr),
@ -138,10 +146,13 @@ int main(int argc, char **argv) {
plugInName, plugInName,
workingDir); workingDir);
//update.checkJsonVersions(); update.doUpdate(filesToUpdate, mountPath.has_value());
update.doUpdate(filesToUpdate); update.checkJsonVersions();
update.checkJsonVersions(filesToUpdate); //update.checkJsonVersions(filesToUpdate);
if (mountPath.has_value()) {
System::umountUSBStick();
}
//return a.exec();
return 0; return 0;
} }

View File

@ -138,10 +138,11 @@ Update::~Update() {
unloadDCPlugin(); unloadDCPlugin();
} }
bool Update::doUpdate(QStringList const &filesToWorkOn) { bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) {
if (!m_hw) { if (!m_hw) {
qCritical() << "ERROR!!! m_hw == nullptr"; qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return false; return false;
} }
@ -149,10 +150,12 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
while ((m_sys_areDCdataValid = m_hw->sys_areDCdataValid()) == false) { while ((m_sys_areDCdataValid = m_hw->sys_areDCdataValid()) == false) {
// must deliver 'true', only then are all data from hwapi valid // must deliver 'true', only then are all data from hwapi valid
if (--tries < 0) { if (--tries < 0) {
qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED"; qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
return false; return false;
} }
qCritical() << "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")"; qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true); m_hw->dc_autoRequest(true);
QThread::msleep(500); QThread::msleep(500);
} }
@ -161,7 +164,8 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
QList<QString>::const_iterator it; QList<QString>::const_iterator it;
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) { for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
QString const &fToWorkOn = QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed()); QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed())
: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed());
if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive) if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
@ -203,6 +207,25 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
} }
bool Update::checkJsonVersions(QStringList const& jsonFileNames) { bool Update::checkJsonVersions(QStringList const& jsonFileNames) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return 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() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
return false;
}
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) { for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) {
@ -231,6 +254,7 @@ bool Update::checkJsonVersions(QStringList const& jsonFileNames) {
bool ok = false; bool ok = false;
int n = captured.toInt(&ok); int n = captured.toInt(&ok);
if (ok) { if (ok) {
// note: use 5 (instead of 4 -> index has been shifted)
jsonNr = n + 5; jsonNr = n + 5;
} }
} }
@ -390,10 +414,6 @@ bool Update::downloadJson(enum FileTypeJson type,
} }
} }
m_hw->dc_autoRequest(false);
qDebug() << "SET AUTO-REQUEST=FALSE";
QThread::sleep(1); // make sure the auto-request flag is acknowledged
return ret; return ret;
} }

View File

@ -58,7 +58,7 @@ public:
virtual ~Update() override; virtual ~Update() override;
bool doUpdate(QStringList const &jsonFilesToDownload); bool doUpdate(QStringList const &jsonFilesToDownload, bool usbStickDetected = false);
bool updatePrinterTemplate(int templateIdx, QString fname) const; bool updatePrinterTemplate(int templateIdx, QString fname) const;
bool updateConfig(QString jsFileToSendToDC); bool updateConfig(QString jsFileToSendToDC);

View File

@ -124,7 +124,31 @@ DEFINES += QT_DEPRECATED_WARNINGS
# Only exit() if firmware is configured to be possibly updated, but # Only exit() if firmware is configured to be possibly updated, but
# loading the CA-plugin failed. # loading the CA-plugin failed.
# 1.4.7 : Read Json-file versions of Json-files actually loaded into DC. # 1.4.7 : Read Json-file versions of Json-files actually loaded into DC.
VERSION="1.4.8" # 1.4.8 : Improve reading Json-file versions of Json-files actually loaded
# in DC. If available, show version info instead of blob-info of
# Json file.
# 1.4.9 : Improve ISMAS output: add messages for JSON downloads.
# Do not send CHECK_ISMAS_TRIGGER_SUCCESS to ISMAS for an automatic
# update.
# In case there is an automatic update (00:00-04:00) use M0100 instead
# of U0002.
# 1.4.10 : Fix: for the time being, never set the autoRequest-flag to false.
# 1.4.11 : Fix: remove hard-coded path to git-repos of gitea in mimbach. Read
# from ATBUpdateTool.ini the url for the gitrepositories.
# 1.5.0 : Use ptu-config.atb-comm.de (given in ini-file) as new server for
# customer repositories.
# Fix: allow empty lines in opkg_commands.
# 1.5.1 : Fix: do not use cleanPath() on a url-address.
# 1.5.2 : Remove .ipk and .gz files in /var/cache/opkg.
# 1.5.3 : Build customer_(id) name without right justification.
# 1.5.4 : Try to run opkg-commands even under some error conditions (failure
# of customerEnvironment(), filesToUpdate() or
# syncCustomerRepositoryAndFS().
# 1.5.5 : Call into binary ptuPackageVersion to get installed package
# versions.
# 1.5.6 : Show additional update progress info in status bar.
# 1.5.7 : Add support for dynamic portrait / landscape.
VERSION="1.5.7"
# PLANNED TODOS: # PLANNED TODOS:
# 1: Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT. # 1: Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT.
# 2: Wenn der WAIT-Button aktiv ist, dann wird ein Repository repariert (neu # 2: Wenn der WAIT-Button aktiv ist, dann wird ein Repository repariert (neu

View File

@ -60,6 +60,16 @@ CommandLineParser::CommandLineParser()
QStringList() << "working-directory" << "working-directory", QStringList() << "working-directory" << "working-directory",
QCoreApplication::translate("main", "working directory of update-script."), QCoreApplication::translate("main", "working directory of update-script."),
QCoreApplication::translate("main", "directory"))) QCoreApplication::translate("main", "directory")))
, m_psaConfigDirectoryOption(
QCommandLineOption(
QStringList() << "psa-config-directory" << "psa-config-directory",
QCoreApplication::translate("main", "config directory of json-files sent to dc."),
QCoreApplication::translate("main", "directory")))
, m_psaTariffDirectoryOption(
QCommandLineOption(
QStringList() << "psa-tariff-directory" << "psa-tariff-directory",
QCoreApplication::translate("main", "tariff directory of tariff-json-files."),
QCoreApplication::translate("main", "directory")))
, m_dryRunOption( , m_dryRunOption(
QCommandLineOption( QCommandLineOption(
QStringList() << "d" << "dry-run", QStringList() << "d" << "dry-run",
@ -111,6 +121,12 @@ void CommandLineParser::configure() {
m_workingDirectoryOption.setDefaultValue("/opt/app/tools/atbupdate/"); m_workingDirectoryOption.setDefaultValue("/opt/app/tools/atbupdate/");
m_parser.addOption(m_workingDirectoryOption); m_parser.addOption(m_workingDirectoryOption);
m_psaConfigDirectoryOption.setDefaultValue("etc/psa_config/");
m_parser.addOption(m_psaConfigDirectoryOption);
m_psaTariffDirectoryOption.setDefaultValue("etc/psa_tariff/");
m_parser.addOption(m_psaTariffDirectoryOption);
m_dryRunOption.setDefaultValue("false"); m_dryRunOption.setDefaultValue("false");
m_parser.addOption(m_dryRunOption); m_parser.addOption(m_dryRunOption);
@ -151,6 +167,12 @@ void CommandLineParser::readSettings() {
if (key.contains("working-directory")) { if (key.contains("working-directory")) {
m_workingDir = v.toString(); m_workingDir = v.toString();
} else } else
if (key.contains("psa-config-directory")) {
m_psaConfigDir = v.toString();
} else
if (key.contains("psa-tariff-directory")) {
m_psaTariffDir = v.toString();
} else
if (key.contains("dry-run")) { if (key.contains("dry-run")) {
m_dryRun = (v.toBool() ? "true" : "false"); m_dryRun = (v.toBool() ? "true" : "false");
} else } else
@ -207,6 +229,20 @@ QString CommandLineParser::plugInName() {
return m_plugInName; return m_plugInName;
} }
QString CommandLineParser::psaConfigDir() {
if (m_parser.isSet(m_psaConfigDirectoryOption)) {
m_psaConfigDir = m_parser.value(m_psaConfigDirectoryOption);
}
return m_psaConfigDir;
}
QString CommandLineParser::psaTariffDir() {
if (m_parser.isSet(m_psaTariffDirectoryOption)) {
m_psaTariffDir = m_parser.value(m_psaTariffDirectoryOption);
}
return m_psaTariffDir;
}
QString CommandLineParser::workingDir() { QString CommandLineParser::workingDir() {
if (m_parser.isSet(m_workingDirectoryOption)) { if (m_parser.isSet(m_workingDirectoryOption)) {
m_workingDir = m_parser.value(m_workingDirectoryOption); m_workingDir = m_parser.value(m_workingDirectoryOption);

View File

@ -11,6 +11,8 @@ class CommandLineParser : public QCommandLineParser {
QString m_plugInDir; QString m_plugInDir;
QString m_plugInName; QString m_plugInName;
QString m_workingDir; QString m_workingDir;
QString m_psaConfigDir;
QString m_psaTariffDir;
QString m_dryRun; QString m_dryRun;
QString m_noUpdatePsaHardware; QString m_noUpdatePsaHardware;
QString m_showYoctoVersion; QString m_showYoctoVersion;
@ -29,6 +31,8 @@ class CommandLineParser : public QCommandLineParser {
QCommandLineOption m_alwaysDownloadConfigOption; QCommandLineOption m_alwaysDownloadConfigOption;
QCommandLineOption m_alwaysDownloadDCOption; QCommandLineOption m_alwaysDownloadDCOption;
QCommandLineOption m_workingDirectoryOption; QCommandLineOption m_workingDirectoryOption;
QCommandLineOption m_psaConfigDirectoryOption;
QCommandLineOption m_psaTariffDirectoryOption;
QCommandLineOption m_dryRunOption; QCommandLineOption m_dryRunOption;
QCommandLineOption m_extendedVersionOption; QCommandLineOption m_extendedVersionOption;
QCommandLineOption m_yoctoVersionOption; QCommandLineOption m_yoctoVersionOption;
@ -52,6 +56,8 @@ public:
QString plugInDir(); QString plugInDir();
QString plugInName(); QString plugInName();
QString workingDir(); QString workingDir();
QString psaConfigDir();
QString psaTariffDir();
bool dryRun(); bool dryRun();
bool noUpdatePsaHardware(); bool noUpdatePsaHardware();
bool yoctoVersion(); bool yoctoVersion();

View File

@ -9,14 +9,15 @@
#include <QStringList> #include <QStringList>
GitClient::GitClient(QString const &customerNrStr, GitClient::GitClient(QString const &customerRepositoryPath,
QString const &customerNrStr,
QString const &customerRepository, QString const &customerRepository,
QString const &workingDirectory, QString const &workingDirectory,
QString const &branchName, QString const &branchName,
QObject *parent) QObject *parent)
: QObject(parent) : QObject(parent)
, m_worker(qobject_cast<Worker *>(parent)) , m_worker(qobject_cast<Worker *>(parent))
, m_repositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(customerNrStr)) , m_repositoryPath(customerRepositoryPath)
, m_customerNr(customerNrStr) , m_customerNr(customerNrStr)
, m_workingDirectory(workingDirectory) , m_workingDirectory(workingDirectory)
, m_branchName(branchName) , m_branchName(branchName)
@ -392,6 +393,45 @@ std::optional<QString> GitClient::gitPull() {
if (QDir(m_customerRepository).exists()) { if (QDir(m_customerRepository).exists()) {
qInfo() << "BRANCH NAME" << m_branchName; qInfo() << "BRANCH NAME" << m_branchName;
#if 0
IMPORTANT COMMENT:
If remote host keys are changed, then
export GIT_SSH_COMMAND="ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig"
git pull
leads to the following warning/error message:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:vOD5jF2hglGktqLhK9ABxfEjwEgIK68/v9erdT05NDQ.
Please contact your system administrator.
Add correct host key in /home/root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/root/.ssh/known_hosts:1
Password authentication is disabled to avoid man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
Agent forwarding is disabled to avoid man-in-the-middle attacks.
X11 forwarding is disabled to avoid man-in-the-middle attacks.
Already up to date.
This first part is from ssh itself. Only the last line is the git message.
Here an output of running ATBUpdateTool with a corrupted known-hosts-file:
...
Oct 23 14:18:18 ATB_PTU5 ATBUpdateTool[2696]: ( branchExistsRemotely : 310 ) branch "zg1/zone1" EXISTS REMOTELY. ( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\r\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\r\nIt is also possible that a host key has just been changed.\r\nThe fingerprint for the ECDSA key sent by the remote host is\nSHA256:vOD5jF2hglGktqLhK9ABxfEjwEgIK68/v9erdT05NDQ.\r\nPlease contact your system administrator.\r\nAdd correct host key in /home/root/.ssh/known_hosts to get rid of this message.\r\nOffending ECDSA key in /home/root/.ssh/known_hosts:1\r\nPassword authentication is disabled to avoid man-in-the-middle attacks.\r\nKeyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.\r\nAgent forwarding is disabled to avoid man-in-the-middle attacks.\r\nX11 forwarding is disabled to avoid man-in-the-middle attacks.\r\nbd4e8da4780b1a7d6be3d3ce8419f43ccf7e706f\trefs/heads/zg1/zone1" )
Oct 23 14:18:18 ATB_PTU5 ATBUpdateTool[2696]: EXECUTED "git branch -l" "(runtime 16ms)" with code 0 IN "/opt/app/tools/atbupdate/customer_336"
Oct 23 14:18:18 ATB_PTU5 ATBUpdateTool[2696]: "UPDATE_STEP::PULL_NEW_BRANCH"
Oct 23 14:18:18 ATB_PTU5 ATBUpdateTool[2696]: "BRANCH-NAME zg1/zone1 CONTAINED IN RESULT master\n* zg1/zone1" .....
The download continues.
#endif
Command c("git pull"); Command c("git pull");
if (c.execute(m_customerRepository)) { if (c.execute(m_customerRepository)) {
QString const s = c.getCommandResult().trimmed(); QString const s = c.getCommandResult().trimmed();

View File

@ -22,7 +22,8 @@ class GitClient : public QObject {
bool copyGitConfigFromMaster(); bool copyGitConfigFromMaster();
public: public:
explicit GitClient(QString const &customerNrStr, explicit GitClient(QString const &customerRepositoryUrl,
QString const &customerNrStr,
QString const &repositoryPath, QString const &repositoryPath,
QString const &workingDirectory = QCoreApplication::applicationDirPath(), QString const &workingDirectory = QCoreApplication::applicationDirPath(),
QString const &branchName = "master", QString const &branchName = "master",

View File

@ -342,8 +342,11 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
return std::nullopt; return std::nullopt;
} }
} else { } else {
if (!response.contains("RECORD")) {
// maybe APISM does not send valid JSON: "RECORD SAVED" etc.
printDebugMessage(port, clientIP, clientPort, printDebugMessage(port, clientIP, clientPort,
QString("PARSE ERROR ") + response + " " + parseError.errorString()); QString("PARSE ERROR ") + response + " " + parseError.errorString());
}
::close(sockfd); ::close(sockfd);
return std::nullopt; return std::nullopt;
} }
@ -360,7 +363,19 @@ QString IsmasClient::updateNewsToIsmas(char const *event,
char buf[1024]; char buf[1024];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
QString const ts = QDateTime::currentDateTime().toString(Qt::ISODateWithMs); QDateTime const local(QDateTime::currentDateTime());
QDateTime utc(local);
utc.setTimeSpec(Qt::UTC);
int const diff = (int)local.secsTo(utc); // diff between UTC and local time
QTime t(0, 0, 0);
t = t.addSecs((uint)diff);
QString const st(QString("%1%2").arg(diff < 0 ? "-" : "+").arg(t.toString("hh:mm")));
QString const ts(local.toString(Qt::ISODateWithMs) + st);
snprintf(buf, sizeof(buf)-1, snprintf(buf, sizeof(buf)-1,
"{" "{"
"\"REASON\":\"SW_UP\"," "\"REASON\":\"SW_UP\","
@ -675,7 +690,8 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
"\"libTCP_ZVT_CCPlugin.so\" : {" "\"libTCP_ZVT_CCPlugin.so\" : {"
"\"VERSION\" : \"%s\"" "\"VERSION\" : \"%s\""
"}" "}"
"}" "},"
"\"PTU-PACKAGE-VERSIONS\" : %s"
"}", "}",
psa.versionInfo.reason.toStdString().c_str(), psa.versionInfo.reason.toStdString().c_str(),
psa.versionInfo.created.toStdString().c_str(), psa.versionInfo.created.toStdString().c_str(),
@ -786,7 +802,9 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
psa.pluginVersion.mobilisisCalculatePriceConfigUi.toStdString().c_str(), psa.pluginVersion.mobilisisCalculatePriceConfigUi.toStdString().c_str(),
psa.pluginVersion.prmCalculatePrice.toStdString().c_str(), psa.pluginVersion.prmCalculatePrice.toStdString().c_str(),
psa.pluginVersion.prmCalculatePriceConfigUi.toStdString().c_str(), psa.pluginVersion.prmCalculatePriceConfigUi.toStdString().c_str(),
psa.pluginVersion.tcpZVT.toStdString().c_str()); psa.pluginVersion.tcpZVT.toStdString().c_str(),
psa.ptuPackageVersion.toStdString().c_str());
qInfo() << buf; qInfo() << buf;

View File

@ -77,6 +77,8 @@ struct PSAInstalled {
DC2C print[32]; DC2C print[32];
QString ptuPackageVersion;
explicit PSAInstalled() { explicit PSAInstalled() {
tariff.name = "N/A"; tariff.name = "N/A";
tariff.version = "N/A"; tariff.version = "N/A";

View File

@ -50,9 +50,11 @@
// argv[1]: file to send to dc // argv[1]: file to send to dc
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QByteArray const value = qgetenv("LC_ALL"); QByteArray const value = qgetenv("LC_ALL");
if (value != "C") { if (value.isEmpty() || value != "C") {
qputenv("LC_ALL", "C"); qputenv("LC_ALL", "C");
} }
// qputenv("XDG_RUNTIME_DIR", "/var/run/user/0"); // qputenv("XDG_RUNTIME_DIR", "/var/run/user/0");
openlog("ATB-UPDATE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER); openlog("ATB-UPDATE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
@ -62,7 +64,8 @@ int main(int argc, char *argv[]) {
QApplication::setApplicationVersion(APP_VERSION); QApplication::setApplicationVersion(APP_VERSION);
if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
atbInstallMessageHandler(atbDebugOutput); atbInstallMessageHandler(nullptr);
//atbInstallMessageHandler(atbDebugOutput);
setDebugLevel(LOG_NOTICE); setDebugLevel(LOG_NOTICE);
} }
@ -71,6 +74,38 @@ int main(int argc, char *argv[]) {
parser.readSettings(); parser.readSettings();
QString repositoryUrl = parser.repositoryUrl(); QString repositoryUrl = parser.repositoryUrl();
if (repositoryUrl.endsWith('/')) {
repositoryUrl.chop(1);
}
QString gitSSHCommand("");
if (repositoryUrl.contains("ptu-config.atb-comm.de")) {
QByteArray const v = qgetenv("GIT_SSH_COMMAND");
if (v.isEmpty()) {
QString sshKeyFile("/opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig");
if (QFileInfo(sshKeyFile).exists()) {
gitSSHCommand = "ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig";
if (!qputenv("GIT_SSH_COMMAND", QByteArray(gitSSHCommand.toStdString().c_str()))) {
qCritical() << "ERROR: GIT_SSH_COMMAND not put into env. Exiting...";
return -1;
}
} else {
qCritical() << "ERROR ssh-key-file" << sshKeyFile << "does not exists. Exiting...";
return -1;
}
} else {
gitSSHCommand = QString(v.toStdString().c_str());
qCritical() << "WARNING GIT_SSH_COMMAND already set in enviroment:"
<< gitSSHCommand;
if (gitSSHCommand != "ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig") {
qCritical() << "ERROR" << gitSSHCommand << "wrong. Exiting...";
return -1;
}
}
}
QString plugInDir = parser.plugInDir(); QString plugInDir = parser.plugInDir();
QString plugInName = parser.plugInName(); QString plugInName = parser.plugInName();
QString workingDir = parser.workingDir(); QString workingDir = parser.workingDir();
@ -93,6 +128,9 @@ int main(int argc, char *argv[]) {
qInfo() << "pwd ......................" << rtPath; qInfo() << "pwd ......................" << rtPath;
qInfo() << "repositoryUrl ............" << repositoryUrl; qInfo() << "repositoryUrl ............" << repositoryUrl;
if (!gitSSHCommand.isEmpty()) {
qInfo() << "GIT_SSH_COMMAND .........." << gitSSHCommand;
}
qInfo() << "plugInDir ................" << plugInDir; qInfo() << "plugInDir ................" << plugInDir;
qInfo() << "plugInName ..............." << plugInName; qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir; qInfo() << "workingDir ..............." << workingDir;

View File

@ -12,6 +12,9 @@
#include <QScrollBar> #include <QScrollBar>
#include <QEvent> #include <QEvent>
#include <QScreen>
MainWindow::MainWindow(Worker *worker, QWidget *parent) MainWindow::MainWindow(Worker *worker, QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -30,6 +33,7 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
this->statusBar()->setFont(f); this->statusBar()->setFont(f);
ui->setupUi(this); ui->setupUi(this);
checkOrientation();
ui->updateProgress->setRange(0, 100); ui->updateProgress->setRange(0, 100);
ui->updateProgress->reset(); ui->updateProgress->reset();
@ -59,6 +63,24 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
m_exitTimer->setSingleShot(true); m_exitTimer->setSingleShot(true);
m_exitTimer->start(1800 * 1000); m_exitTimer->start(1800 * 1000);
m_statusTimer = new QTimer(this);
if (m_statusTimer) {
connect(m_statusTimer, &QTimer::timeout, [this]() {
static QString p(".");
QTime const &t = QDateTime::currentDateTime().time();
QString s = t.toString(Qt::ISODate);
s += ": Update might take several minutes " + p;
if (p.length() >= 5) {
p = ".";
} else {
p += ".";
}
this->statusBar()->showMessage(s);
});
m_statusTimer->setSingleShot(false);
m_statusTimer->start(1000);
}
connect(ui->exit, SIGNAL(clicked()),this,SLOT(onQuit())); connect(ui->exit, SIGNAL(clicked()),this,SLOT(onQuit()));
connect(m_worker, SIGNAL(disableExit()),this,SLOT(onDisableExit())); connect(m_worker, SIGNAL(disableExit()),this,SLOT(onDisableExit()));
connect(m_worker, SIGNAL(enableExit()),this,SLOT(onEnableExit())); connect(m_worker, SIGNAL(enableExit()),this,SLOT(onEnableExit()));
@ -76,9 +98,60 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
MainWindow::~MainWindow() { MainWindow::~MainWindow() {
delete m_startTimer; delete m_startTimer;
delete m_exitTimer; delete m_exitTimer;
delete m_statusTimer;
delete ui; delete ui;
} }
// ----------------------------- Ui::LAYOUT setting -------------------------------------
void MainWindow::checkOrientation()
{
QScreen *screen = QGuiApplication::primaryScreen();
Qt::ScreenOrientation orientation = screen->orientation();
switch (orientation) {
case Qt::PrimaryOrientation:
this->setLandscapeLayout();
break;
case Qt::LandscapeOrientation:
this->setLandscapeLayout();
break;
case Qt::PortraitOrientation:
this->setPortraitLayout();
break;
case Qt::InvertedLandscapeOrientation:
this->setLandscapeLayout();
break;
case Qt::InvertedPortraitOrientation:
this->setPortraitLayout();
break;
}
this->currentOrientation = orientation;
}
void MainWindow::setPortraitLayout()
{
// Adjust layout for portrait mode (480x800)
this->setFixedSize(480, 800);
ui->centralwidget->setFixedSize(480, 800);
}
void MainWindow::setLandscapeLayout()
{
// Adjust layout for landscape mode (800x480)
this->setFixedSize(800, 480);
ui->centralwidget->setFixedSize(800, 480);
}
void MainWindow::customEvent(QEvent *event) { void MainWindow::customEvent(QEvent *event) {
if (event->type() == ProgressEvent::type()) { if (event->type() == ProgressEvent::type()) {
ProgressEvent *pevent = (ProgressEvent *)event; ProgressEvent *pevent = (ProgressEvent *)event;

View File

@ -66,6 +66,12 @@ private:
void onShowMessage(QString, QString); void onShowMessage(QString, QString);
Ui::MainWindow *ui; Ui::MainWindow *ui;
void checkOrientation();
void setPortraitLayout();
void setLandscapeLayout();
Qt::ScreenOrientation currentOrientation;
Worker *m_worker; Worker *m_worker;
int const m_width; int const m_width;
QTimer *m_startTimer; QTimer *m_startTimer;
@ -73,5 +79,6 @@ private:
bool m_progressRunning; bool m_progressRunning;
//int m_progressValue; //int m_progressValue;
UpdateDcEvent::UpdateStep m_updateStep; UpdateDcEvent::UpdateStep m_updateStep;
QTimer *m_statusTimer;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -10,6 +10,12 @@
<height>480</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="minimumSize">
<size>
<width>480</width>
<height>480</height>
</size>
</property>
<property name="font"> <property name="font">
<font> <font>
<family>Source Code Pro</family> <family>Source Code Pro</family>
@ -19,15 +25,8 @@
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="layoutWidget"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="geometry"> <item>
<rect>
<x>10</x>
<y>10</y>
<width>781</width>
<height>441</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="3" column="2"> <item row="3" column="2">
<widget class="QPushButton" name="exit"> <widget class="QPushButton" name="exit">
@ -52,6 +51,7 @@
<font> <font>
<family>Misc Fixed</family> <family>Misc Fixed</family>
<pointsize>11</pointsize> <pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
@ -61,13 +61,11 @@
<property name="horizontalScrollBarPolicy"> <property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum> <enum>Qt::ScrollBarAsNeeded</enum>
</property> </property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </item>
</layout>
</widget> </widget>
</widget> </widget>
<resources/> <resources/>

View File

@ -57,21 +57,21 @@ bool Command::execute(QString workingDirectory, QStringList args) {
connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError())); connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
if (!args.isEmpty()) { if (!args.isEmpty()) {
qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args //qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args
<< "IN" << p->workingDirectory(); // << "IN" << p->workingDirectory();
p->start(m_command, args); p->start(m_command, args);
} else { } else {
qDebug() << "START COMMAND" << m_command //qDebug() << "START COMMAND" << m_command
<< "IN" << p->workingDirectory(); // << "IN" << p->workingDirectory();
p->start(m_command); p->start(m_command);
} }
qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch(); qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch();
if (p->waitForStarted(m_waitForStartTimeout)) { if (p->waitForStarted(m_waitForStartTimeout)) {
qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory(); // qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory();
if (p->state() == QProcess::ProcessState::Running) { if (p->state() == QProcess::ProcessState::Running) {
qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory(); // qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory();
// wait forever for git/opkg-commands to finish // wait forever for git/opkg-commands to finish
int wait = m_waitForFinishTimeout; int wait = m_waitForFinishTimeout;
if (m_command.trimmed().startsWith("git", Qt::CaseInsensitive) || if (m_command.trimmed().startsWith("git", Qt::CaseInsensitive) ||
@ -80,7 +80,7 @@ bool Command::execute(QString workingDirectory, QStringList args) {
} }
bool const no_timeout = p->waitForFinished(wait); bool const no_timeout = p->waitForFinished(wait);
if (no_timeout) { if (no_timeout) {
qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory(); // qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory();
if (p->exitStatus() == QProcess::NormalExit) { if (p->exitStatus() == QProcess::NormalExit) {
if ((m_exitCode = p->exitCode()) == 0) { if ((m_exitCode = p->exitCode()) == 0) {
qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();

View File

@ -193,8 +193,8 @@ bool Update::openSerial(int br, QString baudrate, QString comPort) const {
+ " " + baudrate + " " + comPort + "...OK"); + " " + baudrate + " " + comPort + "...OK");
// m_hw->dc_autoRequest(true); // m_hw->dc_autoRequest(true);
m_hw->dc_autoRequest(false); // m_hw->dc_autoRequest(false);
QThread::sleep(1); // QThread::sleep(1);
Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen())); Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen()));
return true; return true;
@ -394,7 +394,6 @@ bool Update::downloadJson(enum FileTypeJson type,
int templateIdx, int templateIdx,
QString jsFileToSendToDC) const { QString jsFileToSendToDC) const {
bool ret = false;
if (m_hw) { if (m_hw) {
m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag
qDebug() << "SET AUTO-REQUEST=TRUE"; qDebug() << "SET AUTO-REQUEST=TRUE";
@ -411,24 +410,27 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg; lst << msg;
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE)); m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE));
} }
break; break;
} }
} }
QString msg;
lst.clear(); lst.clear();
if (ready) { if (ready) {
QString msg;
QFile file(jsFileToSendToDC); QFile file(jsFileToSendToDC);
QFileInfo fi(jsFileToSendToDC); // max. size of template file is 800 bytes QFileInfo fi(jsFileToSendToDC); // max. size of template file is 800 bytes
if (file.exists()) { if (file.exists()) {
if (file.open(QIODevice::ReadOnly)) { if (file.open(QIODevice::ReadOnly)) {
if (fi.size() > 0 && fi.size() <= 800) { if (fi.size() > 0 && fi.size() <= 800) {
QByteArray ba = file.readAll(); QByteArray ba = file.readAll();
// kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
// nrOfTemplate=1...32 if kindOfFile==6 // nrOfTemplate=1...32 if kindOfFile==6
// content = content of the Json file, max 800byte ascii signs // content = content of the Json file, max 800byte ascii signs
// type == kindOfFile
if (m_hw->sys_sendJsonFileToDc((uint8_t)(type), if (m_hw->sys_sendJsonFileToDc((uint8_t)(type),
templateIdx, templateIdx,
(uint8_t *)ba.data())) { (uint8_t *)ba.data())) {
@ -461,17 +463,20 @@ bool Update::downloadJson(enum FileTypeJson type,
*/ */
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE)); lst.clear();
if (templateIdx >= 1 && templateIdx <= 32) {
lst << QString("LOADED %1 (%2) TO DC").arg(fi.fileName()).arg(templateIdx);
} else {
lst << QString("LOADED %1 (%2) TO DC").arg(fi.fileName()).arg((uint8_t)type);
}
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE));
} }
ret = true;
} else { } else {
msg = QString("ERROR SEND JSON-FILE %1 TO DC").arg(file.fileName()); msg = QString("ERROR SEND JSON-FILE %1 TO DC").arg(file.fileName());
Utils::printCriticalErrorMsg(msg); Utils::printCriticalErrorMsg(msg);
lst << msg; lst << msg;
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
<< Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
} }
} }
} else { } else {
@ -479,8 +484,7 @@ bool Update::downloadJson(enum FileTypeJson type,
Utils::printCriticalErrorMsg(msg); Utils::printCriticalErrorMsg(msg);
lst << msg; lst << msg;
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
<< Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
} }
} }
} else { } else {
@ -489,8 +493,7 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg; lst << msg;
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
<< Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
} }
} }
} else { } else {
@ -499,18 +502,17 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg; lst << msg;
if (m_worker) { if (m_worker) {
m_worker->ISMAS(lst) << (m_worker->GUI(lst) << (m_worker->CONSOLE(lst) m_worker->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
<< Worker::UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
} }
} }
} }
m_hw->dc_autoRequest(false); // m_hw->dc_autoRequest(false);
qDebug() << "SET AUTO-REQUEST=FALSE"; // qDebug() << "SET AUTO-REQUEST=FALSE";
QThread::sleep(1); // make sure the auto-request flag is acknowledged // QThread::sleep(1); // make sure the auto-request flag is acknowledged
} }
return ret; return true;
} }
bool Update::updatePrinterTemplate(int templateIdx, QString jsFile) const { bool Update::updatePrinterTemplate(int templateIdx, QString jsFile) const {
@ -518,14 +520,18 @@ bool Update::updatePrinterTemplate(int templateIdx, QString jsFile) const {
} }
bool Update::updateConfig(QString jsFile) { bool Update::updateConfig(QString jsFile) {
// IMPORTANT: the JSON-file has a 'title'-line: the value MUST be 'DC2C_config'
return downloadJson(FileTypeJson::CONFIG, 0, jsFile); return downloadJson(FileTypeJson::CONFIG, 0, jsFile);
} }
bool Update::updateCashConf(QString jsFile) { bool Update::updateCashConf(QString jsFile) {
// IMPORTANT: the JSON-file has a 'title'-line: the value MUST be 'DC2C_cash '
// Note the twp spaces after DC2C_cash !!
return downloadJson(FileTypeJson::CASH, 0, jsFile); return downloadJson(FileTypeJson::CASH, 0, jsFile);
} }
bool Update::updateDeviceConf(QString jsFile) { bool Update::updateDeviceConf(QString jsFile) {
// IMPORTANT: the JSON-file has a 'title'-line: the value MUST be 'DC2C_device'
return downloadJson(FileTypeJson::DEVICE, 0, jsFile); return downloadJson(FileTypeJson::DEVICE, 0, jsFile);
} }
@ -578,8 +584,8 @@ QStringList Update::getDcSoftAndHardWareVersion() {
QString const &hwVersion = m_hw->dc_getHWversion().toLower().trimmed(); QString const &hwVersion = m_hw->dc_getHWversion().toLower().trimmed();
QString const &swVersion = m_hw->dc_getSWversion().toLower().trimmed(); QString const &swVersion = m_hw->dc_getSWversion().toLower().trimmed();
m_hw->dc_autoRequest(false); //m_hw->dc_autoRequest(false);
QThread::sleep(1); // make sure the timer-slots are inactive //QThread::sleep(1); // make sure the timer-slots are inactive
if (!hwVersion.isEmpty() && !swVersion.isEmpty()) { if (!hwVersion.isEmpty() && !swVersion.isEmpty()) {
return QStringList() << hwVersion << swVersion; return QStringList() << hwVersion << swVersion;
@ -651,6 +657,7 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
bool ok = false; bool ok = false;
int n = captured.toInt(&ok); int n = captured.toInt(&ok);
if (ok) { if (ok) {
// note: the '5' is correct
jsonNr = n + 5; jsonNr = n + 5;
} }
} }
@ -699,6 +706,112 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
return false; return false;
} }
QMap<QString, QString>
Update::getInstalledJsonVersions(QStringList const& jsonFileNames) {
QMap<QString, QString> map;
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return map;
}
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() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
return map;
}
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true);
QThread::msleep(500);
}
for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) {
uint8_t jsonNr = 0;
QString const &fName = jsonFileNames[i];
// send one request for every single version
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 6=printer template 1 ..... 36= template 32
if (fName.endsWith("conf.json")) {
jsonNr = 1;
} else
if (fName.endsWith("device.json")) {
jsonNr = 2;
} else
if (fName.endsWith("cash.json")) {
jsonNr = 3;
} else {
QRegularExpressionMatch match;
static const QRegularExpression re("^(.*print)([0-3][0-9])\\.json\\s*$");
int idx = fName.indexOf(re, 0, &match);
if (idx != -1) {
QString captured = match.captured(match.lastCapturedIndex());
bool ok = false;
int n = captured.toInt(&ok);
if (ok) {
// note: use 5 (instead of 4 -> index has been shifted)
jsonNr = n + 5;
}
}
}
if (jsonNr != 0) {
// send one request for every single version
// jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res.
// 5=printer template 1 ..... 36= template 32
m_hw->sys_requestJsonVersions(jsonNr);
QThread::msleep(500);
char buf[64];
memset(buf, 0x00, sizeof(buf));
m_hw->sys_getJsonVersions(jsonNr, buf);
buf[16] = '\0'; // the DC only handles 16 bytes
static const QByteArray cb(16, (char)0xff);
QString const installedVersion(QString::fromStdString(buf));
QString const fileVersion = getFileVersion(jsonFileNames[i]);
QFileInfo fi(jsonFileNames[i]);
if (cb == QByteArray(buf)) {
map.insert(fi.fileName(), "inst.vers.not.avail");
} else {
map.insert(fi.fileName(), installedVersion);
}
qCritical() << endl;
qCritical() << " json request nr:" << jsonNr;
if (installedVersion == fileVersion) {
qCritical() << " json file:" << fi.fileName();
qCritical() << " installed version in DC:" << installedVersion;
} else
if (cb == QByteArray(buf) && fileVersion == "") {
qCritical() << "unknown json file (repo and DC):" << fi.fileName();
} else {
qCritical() << " json file:" << fi.fileName();
qCritical() << " installed version in DC:" << installedVersion;
qCritical() << " file version in repository:" << fileVersion;
}
} else {
qCritical() << "CANNOT FIND JSON-NR FOR" << fName;
}
}
return map;
}
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) { bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
if (!m_hw) { if (!m_hw) {
@ -838,46 +951,59 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
res = false; res = false;
} else { } else {
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) { if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
Utils::printInfoMsg( if (m_worker) {
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2") QStringList lst(QString("DL:%1 (%2)").arg(QFileInfo(fToWorkOn).fileName()).arg(templateIdx));
.arg(fToWorkOn) m_worker->ISMAS(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS);
.arg(templateIdx));
++displayIndex; ++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")") emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(), + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE); Worker::UPDATE_STEP_DONE);
} }
} }
}
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
if ((res = updateCashConf(fToWorkOn))) { if ((res = updateCashConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn)); if (m_worker) {
QStringList lst(QString("DL:%1").arg(QFileInfo(fToWorkOn).fileName()));
m_worker->ISMAS(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS);
++displayIndex; ++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")") emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(), + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE); Worker::UPDATE_STEP_DONE);
} }
}
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
if ((res= updateConfig(fToWorkOn))) { if ((res= updateConfig(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn)); if (m_worker) {
QStringList lst(QString("DL:%1").arg(QFileInfo(fToWorkOn).fileName()));
m_worker->ISMAS(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS);
++displayIndex; ++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")") emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(), + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE); Worker::UPDATE_STEP_DONE);
} }
}
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive) } else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) { && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true; res = true;
if ((res = updateDeviceConf(fToWorkOn))) { if ((res = updateDeviceConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn)); if (m_worker) {
QStringList lst(QString("DL:%1").arg(QFileInfo(fToWorkOn).fileName()));
m_worker->ISMAS(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS);
++displayIndex; ++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")") emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(), + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE); Worker::UPDATE_STEP_DONE);
} }
}
} else { } else {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn; qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false; res = false;

View File

@ -8,6 +8,7 @@
#include <QByteArray> #include <QByteArray>
#include <QProcess> #include <QProcess>
#include <QPluginLoader> #include <QPluginLoader>
#include <QMap>
#include <DeviceController/interfaces.h> #include <DeviceController/interfaces.h>
@ -60,6 +61,47 @@ public:
bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn); bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
bool checkDownloadedJsonVersions(QStringList const& jsonFileNames); bool checkDownloadedJsonVersions(QStringList const& jsonFileNames);
QMap<QString, QString>
getInstalledJsonVersions(QStringList const& jsonFileNames =
QStringList(
QList(
std::initializer_list<QString>{
QString("etc/psa_config/DC2C_conf.json"),
QString("etc/psa_config/DC2C_cash.json"),
QString("etc/psa_config/DC2C_device.json"),
QString("etc/psa_config/DC2C_print01.json"),
QString("etc/psa_config/DC2C_print02.json"),
QString("etc/psa_config/DC2C_print03.json"),
QString("etc/psa_config/DC2C_print04.json"),
QString("etc/psa_config/DC2C_print05.json"),
QString("etc/psa_config/DC2C_print06.json"),
QString("etc/psa_config/DC2C_print07.json"),
QString("etc/psa_config/DC2C_print08.json"),
QString("etc/psa_config/DC2C_print09.json"),
QString("etc/psa_config/DC2C_print10.json"),
QString("etc/psa_config/DC2C_print11.json"),
QString("etc/psa_config/DC2C_print12.json"),
QString("etc/psa_config/DC2C_print13.json"),
QString("etc/psa_config/DC2C_print14.json"),
QString("etc/psa_config/DC2C_print15.json"),
QString("etc/psa_config/DC2C_print16.json"),
QString("etc/psa_config/DC2C_print17.json"),
QString("etc/psa_config/DC2C_print18.json"),
QString("etc/psa_config/DC2C_print19.json"),
QString("etc/psa_config/DC2C_print20.json"),
QString("etc/psa_config/DC2C_print21.json"),
QString("etc/psa_config/DC2C_print22.json"),
QString("etc/psa_config/DC2C_print23.json"),
QString("etc/psa_config/DC2C_print24.json"),
QString("etc/psa_config/DC2C_print25.json"),
QString("etc/psa_config/DC2C_print26.json"),
QString("etc/psa_config/DC2C_print27.json"),
QString("etc/psa_config/DC2C_print28.json"),
QString("etc/psa_config/DC2C_print29.json"),
QString("etc/psa_config/DC2C_print30.json"),
QString("etc/psa_config/DC2C_print31.json"),
QString("etc/psa_config/DC2C_print32.json")})));
hwinf *hw() { return m_hw; } hwinf *hw() { return m_hw; }
hwinf const *hw() const { return m_hw; } hwinf const *hw() const { return m_hw; }

View File

@ -110,19 +110,19 @@ QString Utils::getTariffInfo(QString fileName) {
} }
QString Utils::zoneName(quint8 i) { QString Utils::zoneName(quint8 i) {
static constexpr char const *zName[] = { //static constexpr char const *zName[] = {
"", // "",
"purple", // "purple",
"blue", // "blue",
"yellow", // "yellow",
"green", // "green",
"yellow (mars)", // "yellow (mars)",
"green (mars)" // "green (mars)"
}; //};
if (i < (sizeof(zName)/sizeof(char const *))) { //if (i < (sizeof(zName)/sizeof(char const *))) {
return zName[i]; // return zName[i];
} //}
return "N/A"; return "---";
} }
void Utils::printCriticalErrorMsg(QString const &errorMsg, bool upper, bool lower) { void Utils::printCriticalErrorMsg(QString const &errorMsg, bool upper, bool lower) {
@ -293,7 +293,7 @@ bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
} }
if (fileNameLst1 != fileNameLst2) { if (fileNameLst1 != fileNameLst2) {
printCriticalErrorMsg(dirPath1 + " AND " + dirPath2 printCriticalErrorMsg(dirPath1 + " AND " + dirPath2
+ " DIFFER: [" + fileNameLst1.join(',') + "],[" + " HAVE DIFFERENT FILES: [" + fileNameLst1.join(',') + "],["
+ fileNameLst2.join(',') + "]"); + fileNameLst2.join(',') + "]");
return false; return false;
} else { } else {
@ -323,7 +323,7 @@ bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
if (gitBlobLst1 != gitBlobLst2) { if (gitBlobLst1 != gitBlobLst2) {
printCriticalErrorMsg(dirPath1 + " AND " + dirPath2 printCriticalErrorMsg(dirPath1 + " AND " + dirPath2
+ " DIFFER: [" + gitBlobLst1.join(',') + "],[" + " HAVE DIFFERENT BLOBS: [" + gitBlobLst1.join(',') + "],["
+ gitBlobLst2.join(',') + "]"); + gitBlobLst2.join(',') + "]");
return false; return false;
} else { } else {

View File

@ -18,6 +18,7 @@
#include <Qt> #include <Qt>
#include <QScopedPointer> #include <QScopedPointer>
#include <QRegularExpression> #include <QRegularExpression>
#include <QJsonArray>
#include "message_handler.h" #include "message_handler.h"
#include <DeviceController/interfaces.h> #include <DeviceController/interfaces.h>
@ -32,6 +33,8 @@ QString const Worker::UPDATE_STEP_WRONG ( "[WRONG]");
QString const Worker::UPDATE_STEP_FAIL ( " [FAIL]"); QString const Worker::UPDATE_STEP_FAIL ( " [FAIL]");
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]"); QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
bool Worker::sendLastVersionOnce = false;
using UPDATE_STEP = Worker::UPDATE_STEP; using UPDATE_STEP = Worker::UPDATE_STEP;
const QMap<UPDATE_STEP, const char*> Worker::smap ( const QMap<UPDATE_STEP, const char*> Worker::smap (
std::initializer_list<std::pair<UPDATE_STEP, const char*>>{ std::initializer_list<std::pair<UPDATE_STEP, const char*>>{
@ -87,6 +90,15 @@ const QMap<UPDATE_STEP, const char*> Worker::smap (
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE), INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE),
@ -130,7 +142,7 @@ Worker::Worker(int customerNr,
char const *serialInterface, char const *serialInterface,
char const *baudrate) char const *baudrate)
: m_customerNr(customerNr) : m_customerNr(customerNr)
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0')) , m_customerNrStr(QString("customer_") + QString::number(m_customerNr))
, m_machineNr(machineNr) , m_machineNr(machineNr)
, m_zoneNr(zoneNr) , m_zoneNr(zoneNr)
, m_pluginDir(pluginDir) , m_pluginDir(pluginDir)
@ -146,7 +158,7 @@ Worker::Worker(int customerNr,
, m_parent(parent) , m_parent(parent)
, m_serialInterface(serialInterface) , m_serialInterface(serialInterface)
, m_baudrate(baudrate) , m_baudrate(baudrate)
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this) , m_gc(m_customerRepositoryPath, m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
, m_versionInfo(QStringList()) , m_versionInfo(QStringList())
, m_osVersion(getOsVersion()) , m_osVersion(getOsVersion())
, m_atbqtVersion(getATBQTVersion()) , m_atbqtVersion(getATBQTVersion())
@ -314,7 +326,7 @@ void Worker::privateUpdate() {
QStringList lst = m_ismasTriggerStatusMessage; QStringList lst = m_ismasTriggerStatusMessage;
// trigger message to ISMAS and CONSOLE // trigger message to ISMAS and CONSOLE
ISMAS(lst) << (CONSOLE(lst) << (m_lastFailedUpdateStep = UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS)); CONSOLE(lst) << (m_lastFailedUpdateStep = UPDATE_STEP::CHECK_ISMAS_TRIGGER_SUCCESS);
// overwrite m_lastFailedUpdateStep // overwrite m_lastFailedUpdateStep
m_lastFailedUpdateStep = UPDATE_STEP::NONE; m_lastFailedUpdateStep = UPDATE_STEP::NONE;
return; return;
@ -445,6 +457,14 @@ void Worker::privateUpdate() {
// //
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = customerEnvironment()) == false) { if ((continueUpdate = customerEnvironment()) == false) {
// even if something goes wrong creating the environment, try to execute
// opkg_commands
if (QDir(m_customerRepository).exists()) {
// always execute contents of opkg_commands-file
m_filesToUpdate.clear();
m_filesToUpdate << "etc/psa_update/opkg_commands";
execOpkgCommands();
}
return; return;
} }
m_versionInfo = m_gc.gitShowReason(m_branchName); m_versionInfo = m_gc.gitShowReason(m_branchName);
@ -459,6 +479,14 @@ void Worker::privateUpdate() {
// //
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = filesToUpdate()) == false) { if ((continueUpdate = filesToUpdate()) == false) {
// even if something goes wrong in filesToUpdate, try to execute
// opkg_commands
if (QDir(m_customerRepository).exists()) {
// always execute contents of opkg_commands-file
m_filesToUpdate.clear();
m_filesToUpdate << "etc/psa_update/opkg_commands";
execOpkgCommands();
}
return; return;
} }
m_versionInfo = m_gc.gitShowReason(m_branchName); m_versionInfo = m_gc.gitShowReason(m_branchName);
@ -472,6 +500,14 @@ void Worker::privateUpdate() {
// //
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if ((continueUpdate = syncCustomerRepositoryAndFS()) == false) { if ((continueUpdate = syncCustomerRepositoryAndFS()) == false) {
// even if something goes wrong with rsync, try to execute
// opkg_commands
if (QDir(m_customerRepository).exists()) {
// always execute contents of opkg_commands-file
m_filesToUpdate.clear();
m_filesToUpdate << "etc/psa_update/opkg_commands";
execOpkgCommands();
}
return; return;
} }
lst = QStringList(QString(smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS])); lst = QStringList(QString(smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS]));
@ -500,9 +536,8 @@ void Worker::privateUpdate() {
if ((continueUpdate = downloadFilesToPSAHardware()) == false) { if ((continueUpdate = downloadFilesToPSAHardware()) == false) {
return; return;
} }
lst = QStringList(QString(smap[UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS])); lst = QStringList(QString("DONE"));
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE)); ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS));
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
@ -854,7 +889,24 @@ bool Worker::computeFilesToDownload() {
return (m_filesToDownload.size() > 0); return (m_filesToDownload.size() > 0);
} }
bool Worker::cleanUpOpkgCache() {
bool removedFiles = true;
QDir dir("/var/cache/opkg");
if (dir.exists()) {
dir.setNameFilters(QStringList() << ".gz" << ".ipk");
dir.setFilter(QDir::Files);
foreach(QString dirFile, dir.entryList()) {
removedFiles &= dir.remove(dirFile);
}
}
return removedFiles;
}
bool Worker::execOpkgCommands() { bool Worker::execOpkgCommands() {
if (!cleanUpOpkgCache()) {
CONSOLE() << "INFO: some cached opkg files not removed";
}
for (int i = 0; i < m_filesToUpdate.size(); ++i) { for (int i = 0; i < m_filesToUpdate.size(); ++i) {
QString const fName = m_filesToUpdate.at(i); QString const fName = m_filesToUpdate.at(i);
if (fName.contains("opkg_commands", Qt::CaseInsensitive)) { if (fName.contains("opkg_commands", Qt::CaseInsensitive)) {
@ -869,10 +921,13 @@ bool Worker::execOpkgCommands() {
QStringList opkgErrorLst; QStringList opkgErrorLst;
while (!in.atEnd()) { while (!in.atEnd()) {
QString line = in.readLine(); QString line = in.readLine();
static const QRegularExpression comment("^\\s*#.*$"); // TODO: "^\\s*[#]{0,}$" : empty line or comment line starting with #
if (line.indexOf(comment, 0) == -1) { static const QRegularExpression comment("^\\s*[#].*$");
// found opkg command static const QRegularExpression emptyLine("^\\s*$");
if (line.indexOf(emptyLine, 0) == -1 &&
line.indexOf(comment, 0) == -1) {
QString opkgCommand = line.trimmed(); QString opkgCommand = line.trimmed();
qCritical() << "Found opkg-command" << opkgCommand;
if (!executeOpkgCommand(opkgCommand)) { if (!executeOpkgCommand(opkgCommand)) {
opkgErrorLst << opkgCommand; opkgErrorLst << opkgCommand;
} else { } else {
@ -951,13 +1006,16 @@ bool Worker::execOpkgCommands() {
bool Worker::downloadFilesToPSAHardware() { bool Worker::downloadFilesToPSAHardware() {
m_displayIndex = 0; m_displayIndex = 0;
QStringList lst(QString("START"));
GUI(m_filesToDownload) << (CONSOLE(m_filesToDownload) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE); ISMAS(lst) << (GUI(m_filesToDownload) << (CONSOLE(m_filesToDownload) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE);
if (m_noUpdatePsaHardware == false) { if (m_noUpdatePsaHardware == false) {
if (computeFilesToDownload() > 0) { if (computeFilesToDownload() > 0) {
QStringList lst = m_filesToDownload; lst.clear();
for (int i = 0; i < m_filesToDownload.size(); ++i) {
lst << QFileInfo(m_filesToDownload.at(i)).fileName();
}
ISMAS(lst) << (CONSOLE(lst) << UPDATE_STEP::FILES_TO_DOWNLOAD); ISMAS(lst) << (CONSOLE(lst) << UPDATE_STEP::FILES_TO_DOWNLOAD);
if (m_update && m_update->doUpdate(m_displayIndex, m_filesToDownload)) { if (m_update && m_update->doUpdate(m_displayIndex, m_filesToDownload)) {
@ -970,7 +1028,7 @@ bool Worker::downloadFilesToPSAHardware() {
return true; return true;
} }
CONSOLE(lst) << (m_lastFailedUpdateStep = UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE); ISMAS(lst) << (CONSOLE(lst) << (m_lastFailedUpdateStep = UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE));
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE); setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE);
return false; return false;
@ -981,14 +1039,20 @@ bool Worker::downloadFilesToPSAHardware() {
} }
bool Worker::syncCustomerRepositoryAndFS() { bool Worker::syncCustomerRepositoryAndFS() {
ISMAS() << (GUI() << (CONSOLE() << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY)); QString msg("START");
QStringList lst(msg);
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY));
lst.clear();
if (QDir(m_customerRepository).exists()) { if (QDir(m_customerRepository).exists()) {
if (QDir::setCurrent(m_customerRepository)) { if (QDir::setCurrent(m_customerRepository)) {
Command md("bash"); Command md("bash");
if (!md.execute(m_customerRepository, if (!md.execute(m_customerRepository,
QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/dc /etc/psa_tariff")) { QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/dc /etc/psa_tariff")) {
qCritical() << "COULD NOT EXECUTE '" << md.command() << "' exitCode=(" << md.exitCode() << ")"; msg = QString("COULD NOT EXECUTE '%1', exitCode=%2").arg(md.command()).arg(md.exitCode());
qCritical() << msg;
QStringList lst2(msg);
ISMAS(lst2) << (CONSOLE(lst2) << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY);
} }
QString const params("-v " QString const params("-v "
"--recursive " "--recursive "
@ -1047,12 +1111,22 @@ bool Worker::syncCustomerRepositoryAndFS() {
error = true; error = true;
} }
} }
if (!error) {
lst.clear();
lst << QString("SUCCESS %1").arg(cmd);
ISMAS(lst) << (CONSOLE(lst) << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY);
} else {
msg = QString("FAILURE %1").arg(cmd);
lst << msg;
QStringList lst2(msg);
ISMAS(lst2) << (CONSOLE(lst2) << UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY);
}
} }
if (!error) { if (!error) {
// now check tariff-files in etc and /etc/psa_tariff // now check tariff-files in etc and /etc/psa_tariff
QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff")); QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff"));
QDir dir2("/etc/psa_tariff"); QDir dir2("/etc/psa_tariff");
if (Utils::sameFilesInDirs(dir1, dir2)) { if (Utils::sameFilesInDirs(dir1, dir2) == false) {
CONSOLE() << QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff") CONSOLE() << QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff")
<< "AND /etc/psa_tariff ARE DIFFERENT: CHANGED CUSTOMER-NUMBER?"; << "AND /etc/psa_tariff ARE DIFFERENT: CHANGED CUSTOMER-NUMBER?";
} }
@ -1060,9 +1134,13 @@ bool Worker::syncCustomerRepositoryAndFS() {
setProgress(_SYNC_CUSTOMER_REPOSITORY_SUCCESS); setProgress(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
return true; return true;
} }
} else {
lst << QString("CAN NOT CD TO CUST-REPO %1").arg(m_customerRepository);
} }
} else {
lst << QString("CUST-REPO %1 DOES NOT EXIST").arg(m_customerRepository);
} }
ISMAS() << (GUI() << (CONSOLE() << (m_lastFailedUpdateStep = UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE))); ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << (m_lastFailedUpdateStep = UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_FAILURE)));
setProgress(_SYNC_CUSTOMER_REPOSITORY_FAILURE); setProgress(_SYNC_CUSTOMER_REPOSITORY_FAILURE);
return false; return false;
} }
@ -1342,20 +1420,36 @@ PSAInstalled Worker::getPSAInstalled() {
psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig; psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig;
psaInstalled.pluginVersion.tcpZVT = m_pluginVersionTcpZvt; psaInstalled.pluginVersion.tcpZVT = m_pluginVersionTcpZvt;
// key: conf-json-filename; value: installed version on DC
QMap<QString, QString> map;
if (m_update) {
map = m_update->getInstalledJsonVersions();
}
psaInstalled.cash.name = "DC2C_cash.json"; psaInstalled.cash.name = "DC2C_cash.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name); absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name);
psaInstalled.cash.blob = m_gc.gitBlob(absPathName); psaInstalled.cash.blob = m_gc.gitBlob(absPathName);
psaInstalled.cash.size = getFileSize(absPathName); psaInstalled.cash.size = getFileSize(absPathName);
if (map.contains("DC2C_cash.json")) {
psaInstalled.cash.blob = map.value("DC2C_cash.json", "inst.vers.not.avail");
}
psaInstalled.conf.name = "DC2C_conf.json"; psaInstalled.conf.name = "DC2C_conf.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name); absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name);
psaInstalled.conf.blob = m_gc.gitBlob(absPathName); psaInstalled.conf.blob = m_gc.gitBlob(absPathName);
psaInstalled.conf.size = getFileSize(absPathName); psaInstalled.conf.size = getFileSize(absPathName);
if (map.contains("DC2C_conf.json")) {
psaInstalled.conf.blob = map.value("DC2C_conf.json", "inst.vers.not.avail");
}
psaInstalled.device.name = "DC2C_device.json"; psaInstalled.device.name = "DC2C_device.json";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name); absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name);
psaInstalled.device.blob = m_gc.gitBlob(absPathName); psaInstalled.device.blob = m_gc.gitBlob(absPathName);
psaInstalled.device.size = getFileSize(absPathName); psaInstalled.device.size = getFileSize(absPathName);
if (map.contains("DC2C_device.json")) {
psaInstalled.device.blob = map.value("DC2C_device.json", "inst.vers.not.avail");
}
for (int i=0; i < 32; ++i) { for (int i=0; i < 32; ++i) {
QString const &n = QString("%1").arg(i+1).rightJustified(2, '0'); QString const &n = QString("%1").arg(i+1).rightJustified(2, '0');
@ -1363,6 +1457,45 @@ PSAInstalled Worker::getPSAInstalled() {
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name); absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name);
psaInstalled.print[i].blob = m_gc.gitBlob(absPathName); psaInstalled.print[i].blob = m_gc.gitBlob(absPathName);
psaInstalled.print[i].size = getFileSize(absPathName); psaInstalled.print[i].size = getFileSize(absPathName);
if (map.contains(psaInstalled.print[i].name)) {
psaInstalled.print[i].blob = map.value(psaInstalled.print[i].name, "inst.vers.not.avail");
}
}
psaInstalled.ptuPackageVersion = "{}";
if (QFile::exists("/usr/bin/ptuPackageVersions")) {
Command c("/usr/bin/ptuPackageVersions -i -o json");
if (c.execute(m_workingDirectory)) {
QString r = c.getCommandResult();
// ptuPackageVersions returns a json-array
QJsonArray const &ja = QJsonDocument::fromJson(r.remove(QRegExp("\\n")).toUtf8()).array();
if (!ja.empty()) {
// transform the array into an object, containing the objects
// of the array (christian needs it this way)
QJsonObject o;
foreach (QJsonValue const &value, ja) {
if (value.isObject()) {
QJsonObject obj = value.toObject();
QStringList keys = obj.keys();
if (!keys.isEmpty()) {
QString const &k = obj.keys().first();
QJsonValue const &v = obj.value(k);
o.insert(k, v);
}
}
}
psaInstalled.ptuPackageVersion =
QJsonDocument(o).toJson(QJsonDocument::Compact);
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR array return by ptuPackageVersions empty";
}
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR executing ptuPackageVersions";
}
} }
return psaInstalled; return psaInstalled;

View File

@ -37,6 +37,7 @@
#define _ISMAS_DONE "U0001" // 100%, Check: Resultcode: 0 #define _ISMAS_DONE "U0001" // 100%, Check: Resultcode: 0
#define _ISMAS_SET_WAIT_OK "U0002" // empty WAIT-button (""), ResultCode: 0 #define _ISMAS_SET_WAIT_OK "U0002" // empty WAIT-button (""), ResultCode: 0
#define _ISMAS_NO_UPDATE_NECESSARY "M0100" // empty WAIT-button (""), ResultCode: 0
#define _ISMAS_FAILURE "U0003" // FAIL #define _ISMAS_FAILURE "U0003" // FAIL
#define _ISMAS_CONTINUE "U0010" // %-values: Update laeuft, Resultcodes entsprechend laufender Schritt #define _ISMAS_CONTINUE "U0010" // %-values: Update laeuft, Resultcodes entsprechend laufender Schritt
#define _ISMAS_RESET_WAIT "ISMAS" // reset WAIT-button to "WAIT" #define _ISMAS_RESET_WAIT "ISMAS" // reset WAIT-button to "WAIT"
@ -79,7 +80,6 @@
#define _SYNC_CUSTOMER_REPOSITORY_SUCCESS (35) #define _SYNC_CUSTOMER_REPOSITORY_SUCCESS (35)
#define _FILES_TO_UPDATE (36) #define _FILES_TO_UPDATE (36)
#define _CHECK_FOR_REPOSITORY_CHANGES_FAILURE (37) #define _CHECK_FOR_REPOSITORY_CHANGES_FAILURE (37)
#define _FILES_TO_DOWNLOAD (38)
#define _EXEC_OPKG_COMMANDS (39) #define _EXEC_OPKG_COMMANDS (39)
#define _EXEC_OPKG_COMMAND_1 (40) #define _EXEC_OPKG_COMMAND_1 (40)
#define _EXEC_OPKG_COMMAND_2 (41) #define _EXEC_OPKG_COMMAND_2 (41)
@ -93,13 +93,23 @@
#define _EXEC_OPKG_COMMAND_LAST (49) #define _EXEC_OPKG_COMMAND_LAST (49)
#define _EXEC_OPKG_COMMAND_FAILURE (50) #define _EXEC_OPKG_COMMAND_FAILURE (50)
#define _EXEC_OPKG_COMMAND_SUCCESS (51) #define _EXEC_OPKG_COMMAND_SUCCESS (51)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE (60) #define _DOWNLOAD_FILES_TO_PSA_HARDWARE (59)
#define _DOWNLOAD_CONFIG_FILE (61) #define _FILES_TO_DOWNLOAD (60)
#define _DOWNLOAD_CONFIG_FILE_SUCCESS (62) #define _DOWNLOAD_CASH_FILE (61)
#define _DOWNLOAD_CONFIG_FILE_FAILURE (63) #define _DOWNLOAD_CASH_FILE_FAILURE (62)
#define _DOWNLOAD_DEVICE_CONTROLLER (64) #define _DOWNLOAD_CASH_FILE_SUCCESS (63)
#define _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS (85) #define _DOWNLOAD_CONFIG_FILE (64)
#define _DOWNLOAD_DEVICE_CONTROLLER_FAILURE (86) #define _DOWNLOAD_CONFIG_FILE_FAILURE (65)
#define _DOWNLOAD_CONFIG_FILE_SUCCESS (66)
#define _DOWNLOAD_DEVICE_FILE (67)
#define _DOWNLOAD_DEVICE_FILE_FAILURE (68)
#define _DOWNLOAD_DEVICE_FILE_SUCCESS (69)
#define _DOWNLOAD_JSON_FILE (70)
#define _DOWNLOAD_JSON_FILE_FAILURE (71)
#define _DOWNLOAD_JSON_FILE_SUCCESS (72)
#define _DOWNLOAD_DEVICE_CONTROLLER (84)
#define _DOWNLOAD_DEVICE_CONTROLLER_FAILURE (85)
#define _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS (86)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE (87) #define _DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE (87)
#define _DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS (88) #define _DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS (88)
#define _SAVE_LOGS (92) #define _SAVE_LOGS (92)
@ -183,6 +193,7 @@ class Worker : public QThread{
QString m_apismVersion; QString m_apismVersion;
bool executeOpkgCommand(QString opkgCommand); bool executeOpkgCommand(QString opkgCommand);
bool cleanUpOpkgCache();
QString getOsVersion() const; QString getOsVersion() const;
QString getATBQTVersion() const; QString getATBQTVersion() const;
QString getATBUpdateToolVersion() const; QString getATBUpdateToolVersion() const;
@ -326,6 +337,15 @@ public:
DOWNLOAD_CONFIG_FILE = _DOWNLOAD_CONFIG_FILE, DOWNLOAD_CONFIG_FILE = _DOWNLOAD_CONFIG_FILE,
DOWNLOAD_CONFIG_FILE_SUCCESS = _DOWNLOAD_CONFIG_FILE_SUCCESS, DOWNLOAD_CONFIG_FILE_SUCCESS = _DOWNLOAD_CONFIG_FILE_SUCCESS,
DOWNLOAD_CONFIG_FILE_FAILURE = _DOWNLOAD_CONFIG_FILE_FAILURE, DOWNLOAD_CONFIG_FILE_FAILURE = _DOWNLOAD_CONFIG_FILE_FAILURE,
DOWNLOAD_CASH_FILE = _DOWNLOAD_CASH_FILE,
DOWNLOAD_CASH_FILE_FAILURE = _DOWNLOAD_CASH_FILE_FAILURE,
DOWNLOAD_CASH_FILE_SUCCESS = _DOWNLOAD_CASH_FILE_SUCCESS,
DOWNLOAD_DEVICE_FILE = _DOWNLOAD_DEVICE_FILE,
DOWNLOAD_DEVICE_FILE_FAILURE = _DOWNLOAD_DEVICE_FILE_FAILURE,
DOWNLOAD_DEVICE_FILE_SUCCESS = _DOWNLOAD_DEVICE_FILE_SUCCESS,
DOWNLOAD_JSON_FILE = _DOWNLOAD_JSON_FILE,
DOWNLOAD_JSON_FILE_FAILURE = _DOWNLOAD_JSON_FILE_FAILURE,
DOWNLOAD_JSON_FILE_SUCCESS = _DOWNLOAD_JSON_FILE_SUCCESS,
DOWNLOAD_DEVICE_CONTROLLER = _DOWNLOAD_DEVICE_CONTROLLER, DOWNLOAD_DEVICE_CONTROLLER = _DOWNLOAD_DEVICE_CONTROLLER,
DOWNLOAD_DEVICE_CONTROLLER_SUCCESS = _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS, DOWNLOAD_DEVICE_CONTROLLER_SUCCESS = _DOWNLOAD_DEVICE_CONTROLLER_SUCCESS,
DOWNLOAD_DEVICE_CONTROLLER_FAILURE = _DOWNLOAD_DEVICE_CONTROLLER_FAILURE, DOWNLOAD_DEVICE_CONTROLLER_FAILURE = _DOWNLOAD_DEVICE_CONTROLLER_FAILURE,
@ -462,6 +482,7 @@ private slots:
private: private:
PSAInstalled getPSAInstalled(); PSAInstalled getPSAInstalled();
static bool sendLastVersionOnce;
void privateUpdate(); void privateUpdate();
bool computeFilesToDownload(); bool computeFilesToDownload();
bool execOpkgCommands(); bool execOpkgCommands();
@ -654,6 +675,24 @@ private:
break; break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE: case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE:
break; break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER: case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
lst << instance->m_debugMsg; lst << instance->m_debugMsg;
Utils::printUpdateStatusMsg(debug, lst); Utils::printUpdateStatusMsg(debug, lst);
@ -1087,12 +1126,34 @@ private:
case UPDATE_STEP::FILES_TO_UPDATE: case UPDATE_STEP::FILES_TO_UPDATE:
ismasClient.setProgressInPercent(_FILES_TO_UPDATE); ismasClient.setProgressInPercent(_FILES_TO_UPDATE);
break; break;
case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE: case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE: {
ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE); ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE);
break; QString const &ismasUpdateNews =
case UPDATE_STEP::FILES_TO_DOWNLOAD: QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::FILES_TO_DOWNLOAD: {
ismasClient.setProgressInPercent(_FILES_TO_DOWNLOAD); ismasClient.setProgressInPercent(_FILES_TO_DOWNLOAD);
break; QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_JSON_FILE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::EXEC_OPKG_COMMANDS: case UPDATE_STEP::EXEC_OPKG_COMMANDS:
ismasClient.setProgressInPercent(_EXEC_OPKG_COMMANDS); ismasClient.setProgressInPercent(_EXEC_OPKG_COMMANDS);
break; break;
@ -1228,15 +1289,180 @@ private:
ismasClient.sendRequestReceiveResponse( ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews); IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break; } break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE: case UPDATE_STEP::DOWNLOAD_CONFIG_FILE: {
ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE); //ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE);
break; ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS: QString const &ismasUpdateNews =
ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_SUCCESS); QString("#M=APISM#C=CMD_EVENT#J=") +
break; ismasClient.updateNewsToIsmas(
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE: _ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_CONFIG_FILE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS: {
//ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_SUCCESS);
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE: {
ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_FAILURE); ismasClient.setProgressInPercent(_DOWNLOAD_CONFIG_FILE_FAILURE);
break; QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
//ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE);
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_CASH_FILE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE_FAILURE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
//ismasClient.setProgressInPercent(_DOWNLOAD_CASH_FILE_SUCCESS);
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
//ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE);
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE_FAILURE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
//ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_FILE_SUCCESS);
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_JSON_FILE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE_FAILURE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::JSON_FILES_DOWNLOAD_ERROR,
smap[UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
ismasClient.setProgressInPercent(_DOWNLOAD_JSON_FILE);
QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER: case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_CONTROLLER); ismasClient.setProgressInPercent(_DOWNLOAD_DEVICE_CONTROLLER);
break; break;
@ -1274,9 +1500,20 @@ private:
case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE: case UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE:
ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE); ismasClient.setProgressInPercent(_DOWNLOAD_FILES_TO_PSA_HARDWARE_FAILURE);
break; break;
case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY: case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY: {
ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY); ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY);
break; QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas(
_ISMAS_CONTINUE,
ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY],
instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews);
} break;
case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS: { case UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS: {
ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY_SUCCESS); ismasClient.setProgressInPercent(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
QString const &ismasUpdateNews = QString const &ismasUpdateNews =
@ -1285,7 +1522,7 @@ private:
_ISMAS_CONTINUE, _ISMAS_CONTINUE,
ismasClient.getProgressInPercent(), ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS, IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY], smap[UPDATE_STEP::SYNC_CUSTOMER_REPOSITORY_SUCCESS],
instance->m_ismasMsg.join(' ').toStdString().c_str(), instance->m_ismasMsg.join(' ').toStdString().c_str(),
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A"); instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse( ismasClient.sendRequestReceiveResponse(
@ -1315,13 +1552,17 @@ private:
ismasClient.setProgressInPercent(_SAVE_LOGS_FAILURE); ismasClient.setProgressInPercent(_SAVE_LOGS_FAILURE);
break; break;
case UPDATE_STEP::SEND_LAST_VERSION: { case UPDATE_STEP::SEND_LAST_VERSION: {
if (Worker::sendLastVersionOnce == false) {
ismasClient.setProgressInPercent(_SEND_LAST_VERSION + _SEND_LAST_VERSION_CORRECTION); ismasClient.setProgressInPercent(_SEND_LAST_VERSION + _SEND_LAST_VERSION_CORRECTION);
ismasClient.sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT, ismasClient.sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_SENDVERSION#J=") + QString("#M=APISM#C=CMD_SENDVERSION#J=") +
ismasClient.updateOfPSASendVersion(instance->getPSAInstalled())); ismasClient.updateOfPSASendVersion(instance->getPSAInstalled()));
Worker::sendLastVersionOnce = true;
}
} break; } break;
case UPDATE_STEP::UPDATE_SUCCEEDED: { case UPDATE_STEP::UPDATE_SUCCEEDED: {
ismasClient.setProgressInPercent(_UPDATE_SUCCEEDED + _UPDATE_SUCCEEDED_CORRECTION); ismasClient.setProgressInPercent(_UPDATE_SUCCEEDED + _UPDATE_SUCCEEDED_CORRECTION);
if (instance->m_automaticUpdate == false) {
QString const &ismasUpdateNews = QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas( ismasClient.updateNewsToIsmas(
@ -1333,13 +1574,14 @@ private:
instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A"); instance->m_versionInfo.size() >= 1 ? instance->m_versionInfo.at(0).toUtf8().constData() : "N/A");
ismasClient.sendRequestReceiveResponse( ismasClient.sendRequestReceiveResponse(
IsmasClient::APISM::DB_PORT, ismasUpdateNews); IsmasClient::APISM::DB_PORT, ismasUpdateNews);
}
} break; } break;
case UPDATE_STEP::UPDATE_ACTIVATED: { case UPDATE_STEP::UPDATE_ACTIVATED: {
ismasClient.setProgressInPercent(_UPDATE_ACTIVATED + _UPDATE_ACTIVATED_CORRECTION); ismasClient.setProgressInPercent(_UPDATE_ACTIVATED + _UPDATE_ACTIVATED_CORRECTION);
QString const &ismasUpdateNews = QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas( ismasClient.updateNewsToIsmas(
_ISMAS_SET_WAIT_OK, // U0002 (instance->m_automaticUpdate ? _ISMAS_NO_UPDATE_NECESSARY : _ISMAS_SET_WAIT_OK), // U0002 or M0100
ismasClient.getProgressInPercent(), ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::SUCCESS, IsmasClient::RESULT_CODE::SUCCESS,
smap[UPDATE_STEP::UPDATE_FINALIZE], smap[UPDATE_STEP::UPDATE_FINALIZE],
@ -1353,7 +1595,7 @@ private:
QString const &ismasUpdateNews = QString const &ismasUpdateNews =
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
ismasClient.updateNewsToIsmas( ismasClient.updateNewsToIsmas(
_ISMAS_SET_WAIT_OK, // U0002 (instance->m_automaticUpdate ? _ISMAS_NO_UPDATE_NECESSARY : _ISMAS_SET_WAIT_OK), // U0002 or M0100
ismasClient.getProgressInPercent(), ismasClient.getProgressInPercent(),
IsmasClient::RESULT_CODE::NO_UPDATE_NECESSARY, IsmasClient::RESULT_CODE::NO_UPDATE_NECESSARY,
smap[UPDATE_STEP::UPDATE_FINALIZE], smap[UPDATE_STEP::UPDATE_FINALIZE],
@ -1548,6 +1790,24 @@ private:
break; break;
case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE: case UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE:
break; break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_CASH_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE: {
} break;
case UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS: {
} break;
case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER: case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER:
break; break;
case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS: case UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_SUCCESS:

View File

@ -3,6 +3,10 @@
#include <QObject> #include <QObject>
#include <QStringList>
#include <optional>
#include <initializer_list>
class System : public QObject class System : public QObject
{ {
@ -13,16 +17,17 @@ private:
static QString errorMsg; static QString errorMsg;
public: public:
static const QStringList allowedJsonFiles;
static bool checkForSDCard(); static bool checkForSDCard();
static bool umountSDCard(); static bool umountSDCard();
static bool checkForUSBStick(); static std::optional<QString> checkForUSBStick(QString const &dirPathUnderMountPath = ".");
static QString getUSBMountPath(); static QString getUSBMountPath(QString const &dirPathUnderMountPath = ".");
static QString getUSBDeviceName();
//static QString getUSBDeviceName();
static bool umountUSBStick(); static bool umountUSBStick();
static bool test_mount(const QString& dev, const QString &mountpoint); static bool test_mount(const QString& dev, const QString &mountpoint);
@ -48,7 +53,7 @@ public:
static QString getPTU4SerialNumber(); static QString getPTU4SerialNumber();
static QString getPTU4MACAddress(); static QString getPTU4MACAddress();
static QStringList getJsonFilesOnUsbStick(QString const &mountPath);
}; };

View File

@ -7,10 +7,52 @@
#include <QRegExp> #include <QRegExp>
#include <QStringList> #include <QStringList>
#include <QDebug> #include <QDebug>
#include <QDirIterator>
//#include "version.h" //#include "version.h"
const QStringList System::allowedJsonFiles =
std::initializer_list<QString>{
QString("DC2C_conf.json"),
QString("DC2C_cash.json"),
QString("DC2C_device.json"),
QString("DC2C_print01.json"),
QString("DC2C_print02.json"),
QString("DC2C_print03.json"),
QString("DC2C_print04.json"),
QString("DC2C_print05.json"),
QString("DC2C_print06.json"),
QString("DC2C_print07.json"),
QString("DC2C_print08.json"),
QString("DC2C_print09.json"),
QString("DC2C_print10.json"),
QString("DC2C_print11.json"),
QString("DC2C_print12.json"),
QString("DC2C_print13.json"),
QString("DC2C_print14.json"),
QString("DC2C_print15.json"),
QString("DC2C_print16.json"),
QString("DC2C_print17.json"),
QString("DC2C_print18.json"),
QString("DC2C_print19.json"),
QString("DC2C_print20.json"),
QString("DC2C_print21.json"),
QString("DC2C_print22.json"),
QString("DC2C_print23.json"),
QString("DC2C_print24.json"),
QString("DC2C_print25.json"),
QString("DC2C_print26.json"),
QString("DC2C_print27.json"),
QString("DC2C_print28.json"),
QString("DC2C_print29.json"),
QString("DC2C_print30.json"),
QString("DC2C_print31.json"),
QString("DC2C_print32.json")
};
QString System::errorMsg = ""; QString System::errorMsg = "";
System::System(QObject *parent) : System::System(QObject *parent) :
@ -209,8 +251,7 @@ bool System::test_dir(const QString& dir)
bool System::checkForUSBStick() std::optional<QString> System::checkForUSBStick(QString const &dirPathUnderMountPath) {
{
#if defined (ARCH_DesktopLinux) #if defined (ARCH_DesktopLinux)
// DEBUG / TEST: // DEBUG / TEST:
if (QFileInfo(getUSBMountPath()).isDir()) if (QFileInfo(getUSBMountPath()).isDir())
@ -219,11 +260,9 @@ bool System::checkForUSBStick()
return false; return false;
#endif #endif
if (getUSBMountPath().isEmpty()) { QString const &mountPath = getUSBMountPath(dirPathUnderMountPath);
return false; // qCritical() << "MOUNT-PATH" << mountPath;
} return mountPath.isEmpty() ? std::nullopt : std::optional<QString>(mountPath);
return true;
} }
@ -235,8 +274,7 @@ bool System::checkForUSBStick()
* Note, do not return an empty string ("") here because a calling method (which could not be * Note, do not return an empty string ("") here because a calling method (which could not be
* identified till now) is relying on this! * identified till now) is relying on this!
*/ */
QString System::getUSBMountPath() QString System::getUSBMountPath(QString const &dirPathUnderMountPath) {
{
#if defined (ARCH_DesktopLinux) #if defined (ARCH_DesktopLinux)
// DEBUG / TEST: // DEBUG / TEST:
@ -277,8 +315,13 @@ QString System::getUSBMountPath()
mountLine = line.split(' '); mountLine = line.split(' ');
if (mountLine.size() > 3) { if (mountLine.size() > 3) {
qDebug() << "System::getUSBMountPath(): " << mountLine.at(0) << " is mounted on " << mountLine.at(2); qCritical() << "System::getUSBMountPath(): " << mountLine.at(0) << " is mounted on " << mountLine.at(2);
QDir d(QDir::cleanPath(mountLine.at(2) + QDir::separator() + dirPathUnderMountPath));
if (d.exists()) {
return mountLine.at(2); return mountLine.at(2);
} else {
qCritical() << "directory" << d.absolutePath() << "does not exist";
}
} }
} }
} }
@ -289,6 +332,27 @@ QString System::getUSBMountPath()
return ""; return "";
} }
QStringList System::getJsonFilesOnUsbStick(QString const &mountPath) {
QStringList jsonFiles;
// /media/sda2/etc/psa_config
QString const &dirPath = QDir::cleanPath(mountPath + QDir::separator() + "etc" + QDir::separator() + "psa_config");
QDir d(dirPath);
if (d.exists()) {
QDirIterator it(dirPath, QStringList() << "*.json", QDir::Files, QDirIterator::NoIteratorFlags);
while (it.hasNext()) {
QString const &jsonFile = it.next();
QFileInfo fi(jsonFile);
if (System::allowedJsonFiles.contains(fi.fileName())) {
jsonFiles << jsonFile;
} else {
qCritical() << "Warning:" << fi.fileName() << "unknown";
}
}
}
return jsonFiles;
}
/******************************************************************************** /********************************************************************************
* static function to check if a mounted sd-card is writable. * static function to check if a mounted sd-card is writable.