Compare commits

..

65 Commits

Author SHA1 Message Date
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
27 changed files with 2120 additions and 206 deletions

View File

@@ -1,9 +1,12 @@
[REPOSITORY_URL]
repository-url="https://git.mimbach49.de/GerhardHoffmann"
repository-url="gitea@ptu-config.atb-comm.de:ATB/"
[DIRECTORIES]
plugin-directory="/usr/lib/"
working-directory="/opt/app/tools/atbupdate/"
psa-config-directory="etc/psa_config/"
psa-tariff-directory="etc/psa_tariff/"
[PLUGINS]
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}"
!contains(CONFIG, INCLUDEINTERFACES) {
INCLUDEINTERFACES=/opt/ptu5/opt/DCLibraries/include
}
INCLUDEPATH += \
plugins \
$${INCLUDEINTERFACES} \
$${_PRO_FILE_PWD_}/../UpdatePTUDevCtrl \
$${_PRO_FILE_PWD_}/../common/include
CONFIG += c++17
DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
@@ -68,20 +78,25 @@ contains( CONFIG, DesktopLinux ) {
SOURCES += \
main.cpp \
mainwindow.cpp \
sender_thread.cpp \
receiver_thread.cpp \
worker_thread.cpp \
../common/src/message_handler.cpp
../common/src/message_handler.cpp \
../UpdatePTUDevCtrl/commandline_parser.cpp \
update.cpp \
dc_download.cpp \
../common/src/System.cpp
HEADERS += \
mainwindow.h \
sender_thread.h \
receiver_thread.h \
worker_thread.h \
../common/include/message_handler.h
../common/include/message_handler.h \
../UpdatePTUDevCtrl/commandline_parser.h \
update.h \
dc_download.h \
../common/include/System.h
OTHER_FILES += \
ATBDownloadDCFirmware.ini
ATBDownloadDCFirmware.ini \
../ATBUpdateTool.ini
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 <QCoreApplication>
#include <QApplication>
#include <QByteArray>
#include <QProcess>
#include <QCommandLineParser>
#include <QStandardPaths>
#include <QSettings>
#include <QDir>
#include <QDebug>
#include <QTimer>
#include <QFileInfo>
#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 "System.h"
#include <DeviceController/interfaces.h>
#ifdef __linux__
#include <sys/sysinfo.h>
@@ -19,6 +31,20 @@
#define SERIAL_PORT "ttyUSB0"
#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) {
QByteArray const value = qgetenv("LC_ALL");
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);
QApplication a(argc, argv);
QApplication::setApplicationName("ATBUpdateTool");
QApplication::setApplicationName("ATBDownloadDCFirmware");
QApplication::setApplicationVersion(APP_VERSION);
if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
@@ -37,17 +63,73 @@ int main(int argc, char **argv) {
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");
qInfo() << "Main thread" << QThread::currentThreadId();
MainWindow mw;
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 <QEvent>
#ifdef PTU5
#define SERIAL_PORT "ttymxc2"
#else
#define SERIAL_PORT "ttyUSB0"
#endif
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
@@ -79,7 +84,7 @@ MainWindow::~MainWindow() {
bool MainWindow::openSerialPort() {
// const SettingsDialog::Settings p = m_settings->settings();
m_serial->setPortName("");
m_serial->setPortName(SERIAL_PORT);
m_serial->setBaudRate(QSerialPort::Baud115200);
m_serial->setDataBits(QSerialPort::DataBits::Data8);
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
OTHER_FILES += \
ATBDownloadDCJsonFiles.ini
ATBDownloadDCJsonFiles.ini \
../ATBUpdateTool.ini
##########################################################################################

View File

@@ -15,6 +15,7 @@
#include "commandline_parser.h"
#include "utils.h"
#include "update.h"
#include "System.h"
#include <DeviceController/interfaces.h>
@@ -68,6 +69,8 @@ int main(int argc, char **argv) {
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();
@@ -90,6 +93,8 @@ int main(int argc, char **argv) {
qInfo() << "plugInDir ................" << plugInDir;
qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir;
qInfo() << "psaConfigDir ............." << psaConfigDir;
qInfo() << "psaTariffDir ............." << psaTariffDir;
qInfo() << "dryRun ..................." << dryRun;
qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware;
qInfo() << "alwaysDownloadConfig ....." << alwaysDownloadConfig;
@@ -108,15 +113,17 @@ int main(int argc, char **argv) {
return 0;
}
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
QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr));
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()) {
QStringList jsons = dir.entryList(QStringList() << "DC2C*.json", QDir::Files);
if (!jsons.isEmpty()) {
@@ -128,8 +135,9 @@ int main(int argc, char **argv) {
qCritical() << "DIRECTORY" << dir << "DOES NOT EXIST";
return -1;
}
}
qCritical() << "JSON FILES TO UPDATE" << filesToUpdate;
// qCritical() << "JSON FILES TO UPDATE" << filesToUpdate;
Update update(customerRepo,
QString::number(customerNr),
@@ -138,10 +146,13 @@ int main(int argc, char **argv) {
plugInName,
workingDir);
//update.checkJsonVersions();
update.doUpdate(filesToUpdate);
update.checkJsonVersions(filesToUpdate);
update.doUpdate(filesToUpdate, mountPath.has_value());
update.checkJsonVersions();
//update.checkJsonVersions(filesToUpdate);
if (mountPath.has_value()) {
System::umountUSBStick();
}
//return a.exec();
return 0;
}

View File

@@ -138,10 +138,11 @@ Update::~Update() {
unloadDCPlugin();
}
bool Update::doUpdate(QStringList const &filesToWorkOn) {
bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) {
if (!m_hw) {
qCritical() << "ERROR!!! m_hw == nullptr";
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return false;
}
@@ -149,10 +150,12 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
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-SLAVE-PLUGIN NOT CONNECTED";
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED";
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);
QThread::msleep(500);
}
@@ -161,7 +164,8 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
QList<QString>::const_iterator 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)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
@@ -203,6 +207,25 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
}
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) {
@@ -231,6 +254,7 @@ bool Update::checkJsonVersions(QStringList const& jsonFileNames) {
bool ok = false;
int n = captured.toInt(&ok);
if (ok) {
// note: use 5 (instead of 4 -> index has been shifted)
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;
}

View File

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

View File

@@ -124,7 +124,24 @@ DEFINES += QT_DEPRECATED_WARNINGS
# Only exit() if firmware is configured to be possibly updated, but
# loading the CA-plugin failed.
# 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.
VERSION="1.5.3"
# PLANNED TODOS:
# 1: Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT.
# 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",
QCoreApplication::translate("main", "working directory of update-script."),
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(
QCommandLineOption(
QStringList() << "d" << "dry-run",
@@ -111,6 +121,12 @@ void CommandLineParser::configure() {
m_workingDirectoryOption.setDefaultValue("/opt/app/tools/atbupdate/");
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_parser.addOption(m_dryRunOption);
@@ -151,6 +167,12 @@ void CommandLineParser::readSettings() {
if (key.contains("working-directory")) {
m_workingDir = v.toString();
} 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")) {
m_dryRun = (v.toBool() ? "true" : "false");
} else
@@ -207,6 +229,20 @@ QString CommandLineParser::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() {
if (m_parser.isSet(m_workingDirectoryOption)) {
m_workingDir = m_parser.value(m_workingDirectoryOption);

View File

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

View File

@@ -9,14 +9,15 @@
#include <QStringList>
GitClient::GitClient(QString const &customerNrStr,
GitClient::GitClient(QString const &customerRepositoryPath,
QString const &customerNrStr,
QString const &customerRepository,
QString const &workingDirectory,
QString const &branchName,
QObject *parent)
: QObject(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_workingDirectory(workingDirectory)
, m_branchName(branchName)
@@ -392,6 +393,38 @@ std::optional<QString> GitClient::gitPull() {
if (QDir(m_customerRepository).exists()) {
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, and could not be fetched easily, as this
process is gone when git itself starts.
Only the last line is the git message.
#endif
Command c("git pull");
if (c.execute(m_customerRepository)) {
QString const s = c.getCommandResult().trimmed();

View File

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

View File

@@ -342,8 +342,11 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
return std::nullopt;
}
} else {
if (!response.contains("RECORD")) {
// maybe APISM does not send valid JSON: "RECORD SAVED" etc.
printDebugMessage(port, clientIP, clientPort,
QString("PARSE ERROR ") + response + " " + parseError.errorString());
}
::close(sockfd);
return std::nullopt;
}
@@ -360,7 +363,19 @@ QString IsmasClient::updateNewsToIsmas(char const *event,
char buf[1024];
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,
"{"
"\"REASON\":\"SW_UP\","

View File

@@ -50,9 +50,11 @@
// argv[1]: file to send to dc
int main(int argc, char *argv[]) {
QByteArray const value = qgetenv("LC_ALL");
if (value != "C") {
if (value.isEmpty() || value != "C") {
qputenv("LC_ALL", "C");
}
// qputenv("XDG_RUNTIME_DIR", "/var/run/user/0");
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);
if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling
atbInstallMessageHandler(atbDebugOutput);
atbInstallMessageHandler(nullptr);
//atbInstallMessageHandler(atbDebugOutput);
setDebugLevel(LOG_NOTICE);
}
@@ -71,6 +74,38 @@ int main(int argc, char *argv[]) {
parser.readSettings();
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 plugInName = parser.plugInName();
QString workingDir = parser.workingDir();
@@ -93,6 +128,9 @@ int main(int argc, char *argv[]) {
qInfo() << "pwd ......................" << rtPath;
qInfo() << "repositoryUrl ............" << repositoryUrl;
if (!gitSSHCommand.isEmpty()) {
qInfo() << "GIT_SSH_COMMAND .........." << gitSSHCommand;
}
qInfo() << "plugInDir ................" << plugInDir;
qInfo() << "plugInName ..............." << plugInName;
qInfo() << "workingDir ..............." << workingDir;

View File

@@ -57,21 +57,21 @@ bool Command::execute(QString workingDirectory, QStringList args) {
connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
if (!args.isEmpty()) {
qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args
<< "IN" << p->workingDirectory();
//qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args
// << "IN" << p->workingDirectory();
p->start(m_command, args);
} else {
qDebug() << "START COMMAND" << m_command
<< "IN" << p->workingDirectory();
//qDebug() << "START COMMAND" << m_command
// << "IN" << p->workingDirectory();
p->start(m_command);
}
qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch();
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) {
qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory();
// qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory();
// wait forever for git/opkg-commands to finish
int wait = m_waitForFinishTimeout;
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);
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 ((m_exitCode = p->exitCode()) == 0) {
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");
// m_hw->dc_autoRequest(true);
m_hw->dc_autoRequest(false);
QThread::sleep(1);
// m_hw->dc_autoRequest(false);
// QThread::sleep(1);
Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen()));
return true;
@@ -394,7 +394,6 @@ bool Update::downloadJson(enum FileTypeJson type,
int templateIdx,
QString jsFileToSendToDC) const {
bool ret = false;
if (m_hw) {
m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag
qDebug() << "SET AUTO-REQUEST=TRUE";
@@ -411,24 +410,27 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg;
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;
}
}
QString msg;
lst.clear();
if (ready) {
QString msg;
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
// type == kindOfFile
if (m_hw->sys_sendJsonFileToDc((uint8_t)(type),
templateIdx,
(uint8_t *)ba.data())) {
@@ -461,17 +463,20 @@ bool Update::downloadJson(enum FileTypeJson type,
*/
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 {
msg = QString("ERROR SEND JSON-FILE %1 TO DC").arg(file.fileName());
Utils::printCriticalErrorMsg(msg);
lst << msg;
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->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
}
}
} else {
@@ -479,8 +484,7 @@ bool Update::downloadJson(enum FileTypeJson type,
Utils::printCriticalErrorMsg(msg);
lst << msg;
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->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
}
}
} else {
@@ -489,8 +493,7 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg;
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->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
}
}
} else {
@@ -499,18 +502,17 @@ bool Update::downloadJson(enum FileTypeJson type,
lst << msg;
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->GUI(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_FAILURE);
}
}
}
m_hw->dc_autoRequest(false);
qDebug() << "SET AUTO-REQUEST=FALSE";
QThread::sleep(1); // make sure the auto-request flag is acknowledged
// m_hw->dc_autoRequest(false);
// qDebug() << "SET AUTO-REQUEST=FALSE";
// QThread::sleep(1); // make sure the auto-request flag is acknowledged
}
return ret;
return true;
}
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) {
// IMPORTANT: the JSON-file has a 'title'-line: the value MUST be 'DC2C_config'
return downloadJson(FileTypeJson::CONFIG, 0, 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);
}
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);
}
@@ -578,8 +584,8 @@ QStringList Update::getDcSoftAndHardWareVersion() {
QString const &hwVersion = m_hw->dc_getHWversion().toLower().trimmed();
QString const &swVersion = m_hw->dc_getSWversion().toLower().trimmed();
m_hw->dc_autoRequest(false);
QThread::sleep(1); // make sure the timer-slots are inactive
//m_hw->dc_autoRequest(false);
//QThread::sleep(1); // make sure the timer-slots are inactive
if (!hwVersion.isEmpty() && !swVersion.isEmpty()) {
return QStringList() << hwVersion << swVersion;
@@ -651,6 +657,7 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
bool ok = false;
int n = captured.toInt(&ok);
if (ok) {
// note: the '5' is correct
jsonNr = n + 5;
}
}
@@ -699,6 +706,112 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
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) {
if (!m_hw) {
@@ -838,46 +951,59 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
res = false;
} else {
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
Utils::printInfoMsg(
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
.arg(fToWorkOn)
.arg(templateIdx));
if (m_worker) {
QStringList lst(QString("DL:%1 (%2)").arg(QFileInfo(fToWorkOn).fileName()).arg(templateIdx));
m_worker->ISMAS(lst) << (m_worker->CONSOLE(lst) << Worker::UPDATE_STEP::DOWNLOAD_JSON_FILE_SUCCESS);
++displayIndex;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
}
} else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateCashConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn));
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;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
} else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res= updateConfig(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn));
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;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
} else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
if ((res = updateDeviceConf(fToWorkOn))) {
Utils::printInfoMsg(QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn));
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;
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
Worker::UPDATE_STEP_DONE);
}
}
} else {
qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
res = false;

View File

@@ -8,6 +8,7 @@
#include <QByteArray>
#include <QProcess>
#include <QPluginLoader>
#include <QMap>
#include <DeviceController/interfaces.h>
@@ -60,6 +61,47 @@ public:
bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
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 const *hw() const { return m_hw; }

View File

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

View File

@@ -32,6 +32,8 @@ QString const Worker::UPDATE_STEP_WRONG ( "[WRONG]");
QString const Worker::UPDATE_STEP_FAIL ( " [FAIL]");
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
bool Worker::sendLastVersionOnce = false;
using UPDATE_STEP = Worker::UPDATE_STEP;
const QMap<UPDATE_STEP, const char*> Worker::smap (
std::initializer_list<std::pair<UPDATE_STEP, const char*>>{
@@ -87,6 +89,15 @@ const QMap<UPDATE_STEP, const char*> Worker::smap (
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_CONFIG_FILE_FAILURE),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_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_SUCCESS),
INSERT_ELEMENT(UPDATE_STEP::DOWNLOAD_DEVICE_CONTROLLER_FAILURE),
@@ -130,7 +141,7 @@ Worker::Worker(int customerNr,
char const *serialInterface,
char const *baudrate)
: 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_zoneNr(zoneNr)
, m_pluginDir(pluginDir)
@@ -146,7 +157,7 @@ Worker::Worker(int customerNr,
, m_parent(parent)
, m_serialInterface(serialInterface)
, 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_osVersion(getOsVersion())
, m_atbqtVersion(getATBQTVersion())
@@ -314,7 +325,7 @@ void Worker::privateUpdate() {
QStringList lst = m_ismasTriggerStatusMessage;
// 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
m_lastFailedUpdateStep = UPDATE_STEP::NONE;
return;
@@ -500,9 +511,8 @@ void Worker::privateUpdate() {
if ((continueUpdate = downloadFilesToPSAHardware()) == false) {
return;
}
lst = QStringList(QString(smap[UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS]));
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS);
lst = QStringList(QString("DONE"));
ISMAS(lst) << (GUI(lst) << (CONSOLE(lst) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE_SUCCESS));
////////////////////////////////////////////////////////////////////////////
//
@@ -854,7 +864,24 @@ bool Worker::computeFilesToDownload() {
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() {
if (!cleanUpOpkgCache()) {
CONSOLE() << "INFO: some cached opkg files not removed";
}
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
QString const fName = m_filesToUpdate.at(i);
if (fName.contains("opkg_commands", Qt::CaseInsensitive)) {
@@ -869,10 +896,13 @@ bool Worker::execOpkgCommands() {
QStringList opkgErrorLst;
while (!in.atEnd()) {
QString line = in.readLine();
static const QRegularExpression comment("^\\s*#.*$");
if (line.indexOf(comment, 0) == -1) {
// found opkg command
// TODO: "^\\s*[#]{0,}$" : empty line or comment line starting with #
static const QRegularExpression comment("^\\s*[#].*$");
static const QRegularExpression emptyLine("^\\s*$");
if (line.indexOf(emptyLine, 0) == -1 &&
line.indexOf(comment, 0) == -1) {
QString opkgCommand = line.trimmed();
qCritical() << "Found opkg-command" << opkgCommand;
if (!executeOpkgCommand(opkgCommand)) {
opkgErrorLst << opkgCommand;
} else {
@@ -951,13 +981,16 @@ bool Worker::execOpkgCommands() {
bool Worker::downloadFilesToPSAHardware() {
m_displayIndex = 0;
QStringList lst(QString("START"));
GUI(m_filesToDownload) << (CONSOLE(m_filesToDownload) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE);
setProgress(_DOWNLOAD_FILES_TO_PSA_HARDWARE);
ISMAS(lst) << (GUI(m_filesToDownload) << (CONSOLE(m_filesToDownload) << UPDATE_STEP::DOWNLOAD_FILES_TO_PSA_HARDWARE));
if (m_noUpdatePsaHardware == false) {
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);
if (m_update && m_update->doUpdate(m_displayIndex, m_filesToDownload)) {
@@ -970,7 +1003,7 @@ bool Worker::downloadFilesToPSAHardware() {
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);
return false;
@@ -981,14 +1014,20 @@ bool Worker::downloadFilesToPSAHardware() {
}
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::setCurrent(m_customerRepository)) {
Command md("bash");
if (!md.execute(m_customerRepository,
QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/dc /etc/psa_tariff")) {
qCritical() << "COULD NOT EXECUTE '" << md.command() << "' exitCode=(" << md.exitCode() << ")";
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 "
"--recursive "
@@ -1047,12 +1086,22 @@ bool Worker::syncCustomerRepositoryAndFS() {
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) {
// now check tariff-files in etc and /etc/psa_tariff
QDir dir1(QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff"));
QDir dir2("/etc/psa_tariff");
if (Utils::sameFilesInDirs(dir1, dir2)) {
if (Utils::sameFilesInDirs(dir1, dir2) == false) {
CONSOLE() << QDir::cleanPath(m_customerRepository + QDir::separator() + "etc/psa_tariff")
<< "AND /etc/psa_tariff ARE DIFFERENT: CHANGED CUSTOMER-NUMBER?";
}
@@ -1060,9 +1109,13 @@ bool Worker::syncCustomerRepositoryAndFS() {
setProgress(_SYNC_CUSTOMER_REPOSITORY_SUCCESS);
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);
return false;
}
@@ -1342,20 +1395,36 @@ PSAInstalled Worker::getPSAInstalled() {
psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig;
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";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name);
psaInstalled.cash.blob = m_gc.gitBlob(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";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name);
psaInstalled.conf.blob = m_gc.gitBlob(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";
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name);
psaInstalled.device.blob = m_gc.gitBlob(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) {
QString const &n = QString("%1").arg(i+1).rightJustified(2, '0');
@@ -1363,6 +1432,9 @@ PSAInstalled Worker::getPSAInstalled() {
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name);
psaInstalled.print[i].blob = m_gc.gitBlob(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");
}
}
return psaInstalled;

View File

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

View File

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

View File

@@ -7,10 +7,52 @@
#include <QRegExp>
#include <QStringList>
#include <QDebug>
#include <QDirIterator>
//#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 = "";
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)
// DEBUG / TEST:
if (QFileInfo(getUSBMountPath()).isDir())
@@ -219,11 +260,9 @@ bool System::checkForUSBStick()
return false;
#endif
if (getUSBMountPath().isEmpty()) {
return false;
}
return true;
QString const &mountPath = getUSBMountPath(dirPathUnderMountPath);
// qCritical() << "MOUNT-PATH" << mountPath;
return mountPath.isEmpty() ? std::nullopt : std::optional<QString>(mountPath);
}
@@ -235,8 +274,7 @@ bool System::checkForUSBStick()
* Note, do not return an empty string ("") here because a calling method (which could not be
* identified till now) is relying on this!
*/
QString System::getUSBMountPath()
{
QString System::getUSBMountPath(QString const &dirPathUnderMountPath) {
#if defined (ARCH_DesktopLinux)
// DEBUG / TEST:
@@ -277,8 +315,13 @@ QString System::getUSBMountPath()
mountLine = line.split(' ');
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);
} else {
qCritical() << "directory" << d.absolutePath() << "does not exist";
}
}
}
}
@@ -289,6 +332,27 @@ QString System::getUSBMountPath()
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.