From cf859659465d90bf6265dd0f293d9b58baa3451d Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 27 Nov 2024 15:54:42 +0100 Subject: [PATCH 01/39] start with downloading dc: parsing command arguments. started to implement the acrual download --- DownloadDCFirmware/main.cpp | 5 + DownloadDCFirmware/update.cpp | 334 +++++++++++++++++++----- DownloadDCFirmware/update.h | 73 +----- UpdatePTUDevCtrl/commandline_parser.cpp | 46 +++- UpdatePTUDevCtrl/commandline_parser.h | 8 +- 5 files changed, 338 insertions(+), 128 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 7c39038..354cb86 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -73,6 +73,7 @@ int main(int argc, char **argv) { QString workingDir = parser.workingDir(); QString psaConfigDir = parser.psaConfigDir(); QString psaTariffDir = parser.psaTariffDir(); + QString dcDir = parser.dcDir(); QString iniFileName = parser.iniFileName(); bool const dryRun = parser.dryRun(); bool const noUpdatePsaHardware = parser.noUpdatePsaHardware(); @@ -81,6 +82,7 @@ int main(int argc, char **argv) { bool const showExtendedVersion = parser.extendedVersion(); bool const alwaysDownloadConfig = parser.alwaysDownloadConfig(); bool const alwaysDownloadDC = parser.alwaysDownloadDC(); + bool const readDCVersion = parser.readDCVersion(); QString const rtPath = QCoreApplication::applicationDirPath(); @@ -109,6 +111,9 @@ int main(int argc, char **argv) { qInfo() << "machineNr ................" << machineNr; qInfo() << "customerNr ..............." << customerNr; qInfo() << "zoneNr ..................." << zoneNr; + qInfo() << "readDCVersion ............" << readDCVersion; + qInfo() << "dcDir ...................." << dcDir; + if (showExtendedVersion) { printf(APP_EXTENDED_VERSION"\n"); diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index c42103f..c8fd39d 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -118,19 +118,8 @@ Update::Update(QString customerRepository, 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; + // carun stoppen } } @@ -138,7 +127,233 @@ Update::~Update() { unloadDCPlugin(); } -bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) { +Update::DownloadResult Update::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; +} + +Update::DownloadResult +Update::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 ) { + // qDebug() << "addr-block" << bNum << "..."; + 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 + qCritical() << "addr-block" << bNum << "...OK"; + 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; +} + +Update::DownloadResult +Update::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; + + // QByteArray b((const char *)(&local[0]), 64); + // qCritical() << "SNDB" << bNum << b.size() << b.toHex(); + + 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 { + qCritical() << "data for block" << bNum << "OK"; + return res; + } + } else { + noAnswerCount += 1; // no answer by now + } + } + // wait max. about 3 seconds + return DownloadResult::TIMEOUT; +} + +bool Update::startBootloader() const { + qDebug() << "starting bootloader..."; + int nTry = 5; + while (--nTry >= 0) { + m_hw->bl_startBL(); + QThread::msleep(5000); + m_hw->bl_checkBL(); + if (m_hw->bl_isUp()) { + qInfo() << "starting bootloader...OK"; + QThread::msleep(5000); + return true; + } else { + qCritical() << "bootloader not up (" << nTry << ")"; + } + } + qCritical() << "starting bootloader...FAILED"; + return false; +} + +bool Update::stopBootloader() const { + qDebug() << "stopping bootloader..."; + int nTry = 5; + while (--nTry >= 0) { + m_hw->bl_stopBL(); + QThread::msleep(500); + if (!m_hw->bl_isUp()) { + qInfo() << "stopping bootloader...OK"; + return true; + } + } + qCritical() << "stopping bootloader...FAILED"; + return false; +} + +bool Update::resetDeviceController() const { + qDebug() << "resetting device controller..."; + m_hw->bl_rebootDC(); + // wait maximally 3 seconds, before starting bootloader + QThread::sleep(1); + qInfo() << "resetting device controller...OK"; + return true; +} + + +QByteArray Update::loadBinaryDCFile(QString const &filename) const { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "loading dc binary" << filename << "..."; + + QFile file(filename); // closed in destructor call + if (!file.exists()) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << file.fileName() << "does not exist"; + return QByteArray(); + } + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "cannot open file" << file.fileName(); + return QByteArray(); + } + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + << "loading dc binary" << filename << "...OK"; + + return file.readAll(); +} +/* + /////////////////////////////////////////////////////////////////////////////// + // + // 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. + */ +bool Update::doUpdate() { + //QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed()) + //: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed()); if (!m_hw) { qCritical() << "(" << __func__ << ":" << __LINE__ << "):" @@ -146,66 +361,58 @@ bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) { 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); - } + 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); - bool res = false; + // fill last block of data to be sent with 0xFF + ba = ba.leftJustified(totalBlocks*64, (char)(0xFF)); - QList::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); + resetDeviceController(); + if (startBootloader()) { + + qCritical() << "DownloadThread::run(): TOTAL NUMBER OF BYTES TO SEND TO DC" << ba.size(); + qCritical() << "DownloadThread::run(): TOTAL NUMBER OF BLOCKS" << totalBlocks; + + int currentBlock = 0; + DownloadResult res = DownloadResult::OK; + qCritical() << "64-byte block " << currentBlock; + while (res != DownloadResult::ERROR && currentBlock < totalBlocks) { + if ((res = sendNextAddress(currentBlock)) != DownloadResult::ERROR) { + if ((res = sendNextDataBlock(ba, currentBlock)) != DownloadResult::ERROR) { + m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); + currentBlock += 1; + } } } - } 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); + + qCritical() << "DownloadThread::run(): last 64-byte block %04d" << 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() << "DownloadThread::run(): ERROR SEND REMAINING" << rest << "BYTES"; + m_hw->bl_sendDataBlock(64, local); + } else { + m_hw->bl_sendLastBlock(); + m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); } - } 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; + qCritical() << "DownloadThread::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK()); } + stopBootloader(); // there is no harm in stopping the bootloader even } - return res; + return false; } +#if 0 bool Update::checkJsonVersions(QStringList const& jsonFileNames) { if (!m_hw) { qCritical() << "(" << __func__ << ":" << __LINE__ << "):" @@ -436,3 +643,4 @@ bool Update::updateCashConf(QString jsFile) { bool Update::updateDeviceConf(QString jsFile) { return downloadJson(FileTypeJson::DEVICE, 0, jsFile); } +#endif diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index daa3037..d8fb96b 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -58,72 +58,21 @@ public: virtual ~Update() override; - bool doUpdate(QStringList const &jsonFilesToDownload, bool usbStickDetected = false); + bool doUpdate(); - bool updatePrinterTemplate(int templateIdx, QString fname) const; - bool updateConfig(QString jsFileToSendToDC); - bool updateCashConf(QString jsFileToSendToDC); - bool updateDeviceConf(QString jsFileToSendToDC); +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 const &dcFilename) const; + bool resetDeviceController() const; + DownloadResult dcDownloadBinary(QByteArray const &b) const; - bool downloadJson(enum FileTypeJson type, int templateIdx, - QString jsFileToSendToDC) const; + QString m_fileToDownload; - - QString getFileVersion(QString const& jsonFileName); - bool checkJsonVersions(QStringList const& jsonFileNames = - QStringList( - QList( - std::initializer_list{ - 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; diff --git a/UpdatePTUDevCtrl/commandline_parser.cpp b/UpdatePTUDevCtrl/commandline_parser.cpp index 3efb346..de3ecdf 100644 --- a/UpdatePTUDevCtrl/commandline_parser.cpp +++ b/UpdatePTUDevCtrl/commandline_parser.cpp @@ -85,7 +85,17 @@ CommandLineParser::CommandLineParser() , m_yoctoInstallStatusOption( QCommandLineOption( QStringList() << "Y" << "yocto-install", - QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."))) { + QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."))) + , m_dcDirectoryOption( + QCommandLineOption( + QStringList() << "dc-directory" << "dc-directory", + QCoreApplication::translate("main", "device controller directory."), + QCoreApplication::translate("main", "directory"))) + , m_readDCVersionOption( + QCommandLineOption( + QStringList() << "D" << "read-dc-version", + QCoreApplication::translate("main", "Show version of device controller."), + QCoreApplication::translate("main", "Show version of device controller."))) { configure(); } @@ -138,6 +148,12 @@ void CommandLineParser::configure() { m_yoctoInstallStatusOption.setDefaultValue("false"); m_parser.addOption(m_yoctoInstallStatusOption); + + m_dcDirectoryOption.setDefaultValue("etc/dc/"); + m_parser.addOption(m_dcDirectoryOption); + + m_readDCVersionOption.setDefaultValue("false"); + m_parser.addOption(m_readDCVersionOption); } void CommandLineParser::readSettings() { @@ -155,7 +171,7 @@ void CommandLineParser::readSettings() { for (QString const &key: keys) { QVariant v = settings.value(key); - qCritical() << __PRETTY_FUNCTION__ + qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << key << " -> " << v.toString(); if (key.contains("repository-url")) { @@ -196,6 +212,12 @@ void CommandLineParser::readSettings() { } else if (key.contains("plugin-name")) { m_plugInName = v.toString(); + } else + if (key.contains("dc-directory")) { + m_dcDir = v.toString(); + } else + if (key.contains("read-dc-version")) { + m_readDCVersion = (v.toBool() ? "true" : "false"); } else { qCritical() << __PRETTY_FUNCTION__ << key << " -> (UNKNOWN) " << v.toString(); @@ -243,6 +265,26 @@ QString CommandLineParser::psaTariffDir() { return m_psaTariffDir; } +QString CommandLineParser::dcDir() { + if (m_parser.isSet(m_dcDirectoryOption)) { + m_dcDir = m_parser.value(m_dcDirectoryOption); + } + return m_dcDir; +} + +bool CommandLineParser::readDCVersion() { + + qCritical() << __func__ << __LINE__; + + if (m_parser.isSet(m_readDCVersionOption)) { + qCritical() << __func__ << __LINE__ << m_readDCVersion; + m_readDCVersion = m_parser.value(m_readDCVersionOption); + qCritical() << __func__ << __LINE__ << m_readDCVersion; + } + qCritical() << __func__ << __LINE__ << m_readDCVersion; + return m_readDCVersion == "false" ? false : true; +} + QString CommandLineParser::workingDir() { if (m_parser.isSet(m_workingDirectoryOption)) { m_workingDir = m_parser.value(m_workingDirectoryOption); diff --git a/UpdatePTUDevCtrl/commandline_parser.h b/UpdatePTUDevCtrl/commandline_parser.h index 22f906a..0a7e4c8 100644 --- a/UpdatePTUDevCtrl/commandline_parser.h +++ b/UpdatePTUDevCtrl/commandline_parser.h @@ -1,4 +1,4 @@ -#ifndef COMMAND_LINE_PARSER_H_INCLUDED +#ifndef COMMAND_LINE_PARSER_H_INCLUDED #define COMMAND_LINE_PARSER_H_INCLUDED #include @@ -21,6 +21,8 @@ class CommandLineParser : public QCommandLineParser { QString m_iniFileName; QString m_alwaysDownloadConfig; QString m_alwaysDownloadDC; + QString m_readDCVersion; + QString m_dcDir; QCommandLineOption m_repositoryUrlOption; QCommandLineOption m_iniFileDirectoryOption; @@ -37,6 +39,8 @@ class CommandLineParser : public QCommandLineParser { QCommandLineOption m_extendedVersionOption; QCommandLineOption m_yoctoVersionOption; QCommandLineOption m_yoctoInstallStatusOption; + QCommandLineOption m_dcDirectoryOption; + QCommandLineOption m_readDCVersionOption; QCommandLineParser m_parser; @@ -65,5 +69,7 @@ public: bool extendedVersion(); bool alwaysDownloadConfig(); bool alwaysDownloadDC(); + bool readDCVersion(); + QString dcDir(); }; #endif // COMMAND_LINE_PARSER_H_INCLUDED From 808f01e1af470aa7dd6f18e5ff6ac44a846af7a2 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Thu, 28 Nov 2024 12:52:14 +0100 Subject: [PATCH 02/39] init some vars to defaults --- UpdatePTUDevCtrl/commandline_parser.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UpdatePTUDevCtrl/commandline_parser.h b/UpdatePTUDevCtrl/commandline_parser.h index 0a7e4c8..082680d 100644 --- a/UpdatePTUDevCtrl/commandline_parser.h +++ b/UpdatePTUDevCtrl/commandline_parser.h @@ -11,8 +11,8 @@ class CommandLineParser : public QCommandLineParser { QString m_plugInDir; QString m_plugInName; QString m_workingDir; - QString m_psaConfigDir; - QString m_psaTariffDir; + QString m_psaConfigDir{"etc/psa_config"}; + QString m_psaTariffDir{"etc/psa_tariff"}; QString m_dryRun; QString m_noUpdatePsaHardware; QString m_showYoctoVersion; @@ -21,8 +21,8 @@ class CommandLineParser : public QCommandLineParser { QString m_iniFileName; QString m_alwaysDownloadConfig; QString m_alwaysDownloadDC; - QString m_readDCVersion; - QString m_dcDir; + QString m_readDCVersion{"false"}; + QString m_dcDir{"etc/dc/"}; QCommandLineOption m_repositoryUrlOption; QCommandLineOption m_iniFileDirectoryOption; From e82b92b95b056e2ac083256924d8bf5c67433d84 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Thu, 28 Nov 2024 12:52:50 +0100 Subject: [PATCH 03/39] Mior: remove debugs --- UpdatePTUDevCtrl/commandline_parser.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/UpdatePTUDevCtrl/commandline_parser.cpp b/UpdatePTUDevCtrl/commandline_parser.cpp index de3ecdf..9c99a6e 100644 --- a/UpdatePTUDevCtrl/commandline_parser.cpp +++ b/UpdatePTUDevCtrl/commandline_parser.cpp @@ -161,8 +161,8 @@ void CommandLineParser::readSettings() { QString const iniFileName = m_parser.value(m_iniFileNameOption); m_iniFileName = QDir::cleanPath(iniFileDir + QDir::separator() + iniFileName); - qCritical() << __PRETTY_FUNCTION__ << " iniFileDir" << iniFileDir; - qCritical() << __PRETTY_FUNCTION__ << "iniFileName" << m_iniFileName; + //qCritical() << __PRETTY_FUNCTION__ << " iniFileDir" << iniFileDir; + //qCritical() << __PRETTY_FUNCTION__ << "iniFileName" << m_iniFileName; if (!m_iniFileName.isEmpty()) { if (QFile(m_iniFileName).exists()) { @@ -171,8 +171,8 @@ void CommandLineParser::readSettings() { for (QString const &key: keys) { QVariant v = settings.value(key); - qCritical() << "(" << __func__ << ":" << __LINE__ << ")" - << key << " -> " << v.toString(); + //qCritical() << "(" << __func__ << ":" << __LINE__ << ")" + // << key << " -> " << v.toString(); if (key.contains("repository-url")) { m_repositoryUrl = v.toString(); @@ -273,15 +273,9 @@ QString CommandLineParser::dcDir() { } bool CommandLineParser::readDCVersion() { - - qCritical() << __func__ << __LINE__; - if (m_parser.isSet(m_readDCVersionOption)) { - qCritical() << __func__ << __LINE__ << m_readDCVersion; m_readDCVersion = m_parser.value(m_readDCVersionOption); - qCritical() << __func__ << __LINE__ << m_readDCVersion; } - qCritical() << __func__ << __LINE__ << m_readDCVersion; return m_readDCVersion == "false" ? false : true; } From e1e2008aa6f6b2979a738f2422a45315a6d1c7de Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Thu, 28 Nov 2024 12:53:44 +0100 Subject: [PATCH 04/39] read dc-verion directly from binary file --- DownloadDCFirmware/DownloadDCFirmware.pro | 2 ++ DownloadDCFirmware/main.cpp | 15 +++++++++++---- DownloadDCFirmware/update.cpp | 17 +++++++++++++++++ DownloadDCFirmware/update.h | 1 + 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/DownloadDCFirmware/DownloadDCFirmware.pro b/DownloadDCFirmware/DownloadDCFirmware.pro index 088f6d1..b32522f 100644 --- a/DownloadDCFirmware/DownloadDCFirmware.pro +++ b/DownloadDCFirmware/DownloadDCFirmware.pro @@ -80,6 +80,7 @@ SOURCES += \ mainwindow.cpp \ ../common/src/message_handler.cpp \ ../UpdatePTUDevCtrl/commandline_parser.cpp \ + ../UpdatePTUDevCtrl/process/command.cpp \ update.cpp \ dc_download.cpp \ ../common/src/System.cpp @@ -89,6 +90,7 @@ HEADERS += \ mainwindow.h \ ../common/include/message_handler.h \ ../UpdatePTUDevCtrl/commandline_parser.h \ + ../UpdatePTUDevCtrl/process/command.h \ update.h \ dc_download.h \ ../common/include/System.h diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 354cb86..cd4e0bf 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -114,21 +114,28 @@ int main(int argc, char **argv) { qInfo() << "readDCVersion ............" << readDCVersion; qInfo() << "dcDir ...................." << dcDir; + if (readDCVersion) { + qInfo() << "dc-version ..............." << Update::dcVersion( + QDir::cleanPath(rtPath + QDir::separator() + + QString("customer_%1").arg(customerNr) + QDir::separator() + + dcDir + QDir::separator() + "dc2c.bin")); + } if (showExtendedVersion) { printf(APP_EXTENDED_VERSION"\n"); return 0; } - QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr)); - QStringList filesToUpdate; + + // 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; + // MainWindow mw; - mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint); + // mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint); // mw.showFullScreen(); // qCritical() << "SHOW"; diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index c8fd39d..e6ba2df 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -1,4 +1,5 @@ #include "update.h" +#include "process/command.h" #include #include @@ -21,6 +22,8 @@ #include #include #include +#include +#include #define UPDATE_OPKG (1) #define UPDATE_DC (0) @@ -92,6 +95,20 @@ bool Update::unloadDCPlugin() { return false; } +QString Update::dcVersion(QString const &dcBinFile) { + Command c("bash"); + QStringList param; + + param << "-c" << QString(R"(strings %1 | grep DC2c.\[0-9\] | uniq)").arg(dcBinFile); + + if (c.execute("/tmp", param)) { + return c.getCommandResult().trimmed().split(QRegularExpression("\\s")).first(); + // qInfo() << "(" << __func__ << ":" << __LINE__ << ")" << v; + } + + return ""; +} + class hwapi; Update::Update(QString customerRepository, QString customerNrStr, diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index d8fb96b..e253b59 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -59,6 +59,7 @@ public: virtual ~Update() override; bool doUpdate(); + static QString dcVersion(QString const &dcBinFile); private: DownloadResult sendStatus(int ret) const; From 96828f6e25296a3a75c68ca35140570d5590789b Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 6 Dec 2024 11:48:21 +0100 Subject: [PATCH 05/39] getCommandResult(): reset result if necessary (for instance for showing current result in GUI. --- UpdatePTUDevCtrl/process/command.cpp | 17 ++++++++++++++--- UpdatePTUDevCtrl/process/command.h | 6 ++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/UpdatePTUDevCtrl/process/command.cpp b/UpdatePTUDevCtrl/process/command.cpp index 8e0cf68..ab8f40d 100644 --- a/UpdatePTUDevCtrl/process/command.cpp +++ b/UpdatePTUDevCtrl/process/command.cpp @@ -5,6 +5,7 @@ #include #include #include +#include Command::Command(QString const &command, int start_timeout, int finish_timeout) : m_command(command.trimmed()) @@ -14,14 +15,23 @@ Command::Command(QString const &command, int start_timeout, int finish_timeout) , m_exitCode(-1) { } -QString Command::getCommandResult() const { - return m_commandResult; +QString Command::getCommandResult(bool reset) const { + QMutexLocker locker(&m_mtx); + + if (reset == false) { + return m_commandResult; + } + + QString commandResult = m_commandResult; + m_commandResult.clear(); + + return commandResult; } void Command::readyReadStandardOutput() { + QMutexLocker locker(&m_mtx); QProcess *p = (QProcess *)sender(); m_commandResult += p->readAllStandardOutput(); - // qCritical() << m_commandResult; } void Command::readyReadStandardError() { @@ -35,6 +45,7 @@ void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) { // read all remaining data sent to the process, just in case QString d = p->readAllStandardOutput(); if (!d.isEmpty()) { + QMutexLocker locker(&m_mtx); m_commandResult += d; } disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardOutput())); diff --git a/UpdatePTUDevCtrl/process/command.h b/UpdatePTUDevCtrl/process/command.h index bc796ee..460f935 100644 --- a/UpdatePTUDevCtrl/process/command.h +++ b/UpdatePTUDevCtrl/process/command.h @@ -7,22 +7,24 @@ #include #include #include +#include class Command : public QObject { Q_OBJECT QString m_command; - QString m_commandResult; + mutable QString m_commandResult; int m_waitForStartTimeout; int m_waitForFinishTimeout; int m_exitCode; + mutable QMutex m_mtx; public: explicit Command(QString const &command, int start_timeout = 100000, int finish_timeout = 100000); - QString getCommandResult() const; + QString getCommandResult(bool reset = false) const; QString command() const { return m_command; } bool execute(QString workingDirectory, QStringList args = QStringList()); From ec57f9ba20f31490a8ed660689593694f0f7a390 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 6 Dec 2024 11:50:25 +0100 Subject: [PATCH 06/39] Minor: remove unused code. --- UpdatePTUDevCtrl/update.cpp | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/UpdatePTUDevCtrl/update.cpp b/UpdatePTUDevCtrl/update.cpp index 5b9d376..28f7702 100644 --- a/UpdatePTUDevCtrl/update.cpp +++ b/UpdatePTUDevCtrl/update.cpp @@ -133,36 +133,6 @@ Update::Update(Worker *worker, qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_sys_areDCDataValid ..." << m_sys_areDCdataValid; - -#if 0 - QObject const *obj = m_hw->getAPI(); - Q_ASSERT(obj != nullptr); - - QDebug critical = qCritical(); - critical << "connect() to onReportDCDownloadStatus() ..."; - if (!connect(obj, - SIGNAL(hwapi_reportDCDownloadStatus(QString const&)), - this, - SLOT(onReportDCDownloadStatus(QString const &)))) { - critical << "FAILED"; - } else critical << "DONE"; - - critical = qCritical(); - critical << "connect() to onReportDCDownloadSuccess() ..."; - if (!connect(obj, - SIGNAL(hwapi_reportDCDownloadSuccess(QString const&)), this, - SLOT(onReportDCDownloadSuccess(QString const &)))) { - critical << "FAILED"; - } else critical << "DONE"; - - critical = qCritical(); - critical << "connect() to onReportDCDownloadFailure() ..."; - if (!connect(obj, - SIGNAL(hwapi_reportDCDownloadFailure(QString const &)), this, - SLOT(onReportDCDownloadFailure(QString const &)))) { - critical << "FAILED"; - } else critical << "DONE"; -#endif } } From 093d77ddd1f58e6f85916dfe4b0e94a55d7de2c7 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 6 Dec 2024 11:51:06 +0100 Subject: [PATCH 07/39] Update::updateBinary(): begin with starting "/opt/app/tools/atbupdate/ATBDownloadDCFirmware". --- UpdatePTUDevCtrl/update.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/UpdatePTUDevCtrl/update.cpp b/UpdatePTUDevCtrl/update.cpp index 28f7702..837e467 100644 --- a/UpdatePTUDevCtrl/update.cpp +++ b/UpdatePTUDevCtrl/update.cpp @@ -272,7 +272,14 @@ bool Update::isSerialOpen() const { // bootloader is really not running anymore. */ bool Update::updateBinary(QString const &fileToSendToDC) { - qInfo() << "UPDATING DEVICE CONTROLLER FIRMWARE BINARY" << fileToSendToDC; + + QFile dc("/opt/app/tools/atbupdate/ATBDownloadDCFirmware"); + if (dc.exists()) { + qCritical() << "ERROR: dc-binary does not exist" << fileToSendToDC; + return false; + } + + qInfo() << "updating dc-binary" << fileToSendToDC << "..."; return false; From 6b0a784fc8152ebdaea348209538b884add9e78b Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 6 Dec 2024 12:30:54 +0100 Subject: [PATCH 08/39] Remove any reference to device controller as downloading jsons/dc-firmware will be done by ATBDownloadDCJsonFiles and ATBDownloadDCFirmware binaries. --- UpdatePTUDevCtrl/update.cpp | 155 ++++-------------------------------- UpdatePTUDevCtrl/update.h | 7 -- 2 files changed, 15 insertions(+), 147 deletions(-) diff --git a/UpdatePTUDevCtrl/update.cpp b/UpdatePTUDevCtrl/update.cpp index 837e467..29dcd10 100644 --- a/UpdatePTUDevCtrl/update.cpp +++ b/UpdatePTUDevCtrl/update.cpp @@ -105,7 +105,6 @@ Update::Update(Worker *worker, char const *serialInterface, char const *baudrate) : QObject(parent) - , m_hw(loadDCPlugin(QDir(plugInDir), pluginName)) , m_worker(worker) , m_serialInterface(serialInterface) , m_baudrate(baudrate) @@ -116,24 +115,6 @@ Update::Update(Worker *worker, , m_workingDir(workingDir) , m_dryRun(dryRun) , m_sys_areDCdataValid(false) { - - if (!m_hw) { - qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_hw == nullptr -> ca-slave plugin not 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() { @@ -151,43 +132,6 @@ void Update::onReportDCDownloadFailure(QString const &errorMsg) { qCritical() << "msg" << errorMsg; } - - -// br is a index into a table, used for historical reasons. -bool Update::openSerial(int br, QString baudrate, QString comPort) const { - if (m_hw) { - qDebug() << "opening serial" << br << baudrate << comPort << "..."; - if (m_hw->dc_openSerial(br, baudrate, comPort, 1) == true) { // 1 for connect - Utils::printInfoMsg( - QString("OPENING SERIAL %1").arg(br) - + " " + baudrate + " " + comPort + "...OK"); - - // m_hw->dc_autoRequest(true); - // m_hw->dc_autoRequest(false); - // QThread::sleep(1); - - Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen())); - return true; - } - - Utils::printCriticalErrorMsg( - QString("OPENING SERIAL %1").arg(br) - + " " + baudrate + " " + comPort + "...FAILED"); - } - return false; -} - -void Update::closeSerial() const { - qInfo() << "CLOSED SERIAL" << m_baudrate << m_serialInterface; - if (m_hw) { - m_hw->dc_closeSerial(); - } -} - -bool Update::isSerialOpen() const { - return m_hw ? m_hw->dc_isPortOpen() : false; -} - /* /////////////////////////////////////////////////////////////////////////////// @@ -282,95 +226,13 @@ bool Update::updateBinary(QString const &fileToSendToDC) { qInfo() << "updating dc-binary" << fileToSendToDC << "..."; return false; - -#if 0 - QFile fn(fileToSendToDC); - if (!fn.exists()) { - // output via CONSOLE() etc - return false; - } - - bool bl_isUp = false; - if (m_hw->bl_completeStart()) { - int cnt = 5; - while (--cnt > 0) { - if (m_hw->bl_isUp()) { - bl_isUp = true; - break; - } - } - } - - if (!bl_isUp) { - return false; - } - - if (!m_hw->bl_storeFirmware(fileToSendToDC)) { - m_hw->bl_stopBL(); - return false; - } - - uint16_t const nrOfFirmwareBlocks = m_hw->bl_getNrOfFirmwareBlocks(); - - for (uint16_t blockNr = 0; blockNr <= nrOfFirmwareBlocks; ++blockNr) { - m_hw->bl_blockAutoLoad(blockNr); - - int sleepTime = 0; - while (1) { - if (sleepTime > 1500) { - m_hw->bl_stopBL(); - return false; - } - - int8_t const r = m_hw->bl_blockAutoResponse(); - - // after every "bl_blockAutoLoad()" call this until response - // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete - // 3: error despite repeating, cancel. probably bin file corrupted - // Max duration: 3x no response from BL = 900ms - - switch(r) { - case 1: - /* fall through */ - case 2: - sleepTime = 0; - break; - case 0: { - QThread::msleep(100); - sleepTime += 100; - } break; - case 3: - m_hw->bl_stopBL(); - return false; - default: - m_hw->bl_stopBL(); - return false; // unknown error code - } - } - - m_hw->bl_stopBL(); - } - - return true; -#endif -} - -QString Update::jsonType(enum FileTypeJson type) { - switch (type) { - case FileTypeJson::CASH: return "CASH"; - case FileTypeJson::CONFIG: return "CONFIG"; - case FileTypeJson::PRINTER: return "PRINTER"; - case FileTypeJson::SERIAL: return "SERIAL"; - case FileTypeJson::DEVICE: return "DEVICE"; - case FileTypeJson::TIME: return "TIME"; - } - return "N/A"; } bool Update::downloadJson(enum FileTypeJson type, int templateIdx, QString jsFileToSendToDC) const { +#if 0 if (m_hw) { m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag qDebug() << "SET AUTO-REQUEST=TRUE"; @@ -489,6 +351,7 @@ bool Update::downloadJson(enum FileTypeJson type, // QThread::sleep(1); // make sure the auto-request flag is acknowledged } +#endif return true; } @@ -547,6 +410,7 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) { } QStringList Update::getDcSoftAndHardWareVersion() { +#if 0 if (m_hw) { m_hw->dc_autoRequest(true); QThread::sleep(1); // make sure the timer-slots are active @@ -569,15 +433,17 @@ QStringList Update::getDcSoftAndHardWareVersion() { } } +#endif return QStringList() << "DC HW-version not available" << "DC SW-version not available"; } QString Update::getFileVersion(QString const& jsonFileName) { + QString fileVersion(""); +#if 0 // "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()) { @@ -602,10 +468,12 @@ QString Update::getFileVersion(QString const& jsonFileName) { // qCritical() << "ERROR" << inputFile.fileName() << "does not exist"; } +#endif return fileVersion; } bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) { +#if 0 for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) { @@ -680,6 +548,7 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) { } } +#endif return false; } @@ -687,6 +556,7 @@ QMap Update::getInstalledJsonVersions(QStringList const& jsonFileNames) { QMap map; +#if 0 if (!m_hw) { qCritical() << "(" << __func__ << ":" << __LINE__ << "):" << "ERROR!!! m_hw == nullptr"; @@ -786,11 +656,13 @@ Update::getInstalledJsonVersions(QStringList const& jsonFileNames) { } } +#endif return map; } bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) { +#if 0 if (!m_hw) { Utils::printInfoMsg("CA-PLUGIN NOT LOADED"); return false; @@ -997,4 +869,7 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) { qDebug() << "SET AUTO-REQUEST=TRUE"; return res; +#endif + + return false; } diff --git a/UpdatePTUDevCtrl/update.h b/UpdatePTUDevCtrl/update.h index b70c02a..4abdd28 100644 --- a/UpdatePTUDevCtrl/update.h +++ b/UpdatePTUDevCtrl/update.h @@ -22,7 +22,6 @@ class Worker; class Update : public QObject { Q_OBJECT - hwinf *m_hw = nullptr; Worker *m_worker = nullptr; char const *m_serialInterface; char const *m_baudrate; @@ -102,12 +101,6 @@ public: 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; } - - //QString customerId() { return m_customerId; } - //QString const customerId() const { return m_customerId; } - QString branchName() { return m_branchName; } QString const branchName() const { return m_branchName; } From 518bd870336d61b9b32424d668750c3923cc9387 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 20 Dec 2024 13:01:34 +0100 Subject: [PATCH 09/39] save for christmas --- DownloadDCFirmware/DownloadDCFirmware.pro | 2 - DownloadDCFirmware/main.cpp | 58 +++++++-- DownloadDCFirmware/update.cpp | 135 +++++++++++++------- DownloadDCFirmware/update.h | 16 ++- UpdatePTUDevCtrl/commandline_parser.cpp | 4 +- UpdatePTUDevCtrl/git/git_client.cpp | 1 + UpdatePTUDevCtrl/git/git_client.h | 2 +- UpdatePTUDevCtrl/main.cpp | 5 + UpdatePTUDevCtrl/mainwindow.cpp | 56 +++++++-- UpdatePTUDevCtrl/mainwindow.h | 7 ++ UpdatePTUDevCtrl/mainwindow.ui | 147 +++++++++++++++------- UpdatePTUDevCtrl/process/command.cpp | 76 ++++++++++- UpdatePTUDevCtrl/process/command.h | 7 +- UpdatePTUDevCtrl/utils.cpp | 56 +++++++++ UpdatePTUDevCtrl/utils.h | 3 + UpdatePTUDevCtrl/worker.cpp | 85 +++++++++++++ UpdatePTUDevCtrl/worker.h | 14 ++- common/include/System.h | 5 +- common/src/System.cpp | 106 +++++++++++++++- 19 files changed, 665 insertions(+), 120 deletions(-) diff --git a/DownloadDCFirmware/DownloadDCFirmware.pro b/DownloadDCFirmware/DownloadDCFirmware.pro index b32522f..088f6d1 100644 --- a/DownloadDCFirmware/DownloadDCFirmware.pro +++ b/DownloadDCFirmware/DownloadDCFirmware.pro @@ -80,7 +80,6 @@ SOURCES += \ mainwindow.cpp \ ../common/src/message_handler.cpp \ ../UpdatePTUDevCtrl/commandline_parser.cpp \ - ../UpdatePTUDevCtrl/process/command.cpp \ update.cpp \ dc_download.cpp \ ../common/src/System.cpp @@ -90,7 +89,6 @@ HEADERS += \ mainwindow.h \ ../common/include/message_handler.h \ ../UpdatePTUDevCtrl/commandline_parser.h \ - ../UpdatePTUDevCtrl/process/command.h \ update.h \ dc_download.h \ ../common/include/System.h diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index cd4e0bf..4c508fa 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -52,7 +52,7 @@ int main(int argc, char **argv) { } // qputenv("XDG_RUNTIME_DIR", "/var/run/user/0"); - openlog("ATB-UPDATE-DC-FIRMWARE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER); + openlog("DC", LOG_PERROR | LOG_CONS, LOG_USER); QApplication a(argc, argv); QApplication::setApplicationName("ATBDownloadDCFirmware"); @@ -73,7 +73,7 @@ int main(int argc, char **argv) { QString workingDir = parser.workingDir(); QString psaConfigDir = parser.psaConfigDir(); QString psaTariffDir = parser.psaTariffDir(); - QString dcDir = parser.dcDir(); + QString psaDcDir = parser.dcDir(); QString iniFileName = parser.iniFileName(); bool const dryRun = parser.dryRun(); bool const noUpdatePsaHardware = parser.noUpdatePsaHardware(); @@ -112,13 +112,12 @@ int main(int argc, char **argv) { qInfo() << "customerNr ..............." << customerNr; qInfo() << "zoneNr ..................." << zoneNr; qInfo() << "readDCVersion ............" << readDCVersion; - qInfo() << "dcDir ...................." << dcDir; + qInfo() << "dcDir ...................." << psaDcDir; - if (readDCVersion) { - qInfo() << "dc-version ..............." << Update::dcVersion( - QDir::cleanPath(rtPath + QDir::separator() - + QString("customer_%1").arg(customerNr) + QDir::separator() - + dcDir + QDir::separator() + "dc2c.bin")); + if (!QDir(plugInDir).exists()) { + qCritical() << plugInDir + << "does not exists, but has to contain dc-library"; + exit(-1); } if (showExtendedVersion) { @@ -126,12 +125,47 @@ int main(int argc, char **argv) { return 0; } + QString const &customerRepo + = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr)); - // QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr)); - // QStringList filesToUpdate; + // etc/dc: located under mount-path + std::optional mountPath = System::checkForUSBStick(psaDcDir); + QFileInfo fi; + if (mountPath.has_value()) { + fi.setFile(mountPath.value(), System::getDCFileOnUsbStick(mountPath.value())); + } else + if ((mountPath = System::checkForSDCard(psaDcDir)).has_value()) { + fi.setFile(mountPath.value(), System::getDCFileOnSDCard(mountPath.value())); + } else { + qInfo() << "using customer repository" << customerRepo; + + QDir dir(QDir::cleanPath(customerRepo + QDir::separator() + "etc/dc")); + if (dir.exists()) { + fi.setFile(dir, dir.absoluteFilePath("dc2c.bin")); + } else { + qCritical() << "DIRECTORY" << dir << "DOES NOT EXIST"; + return -1; + } + } + + qInfo() << "downloading dc-firmware .." << fi.absoluteFilePath(); + qInfo() << "dc-firmware size (bytes) ." << fi.size(); + if (readDCVersion) { + qInfo() << "dc-version ..............." << Update::dcVersion(fi.absoluteFilePath()); + } QThread::currentThread()->setObjectName("main thread"); - qInfo() << "Main thread" << QThread::currentThreadId(); + // qInfo() << "Main thread" << QThread::currentThreadId(); + + Update update(customerRepo, + QString::number(customerNr), + branchName, + plugInDir, + plugInName, + workingDir, + psaDcDir); + + update.doUpdate(fi.absoluteFilePath()); // MainWindow mw; @@ -142,6 +176,8 @@ int main(int argc, char **argv) { // mw.show(); + qInfo() << ""; + return 0; // return a.exec(); } diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index e6ba2df..dafbc1b 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -96,17 +96,14 @@ bool Update::unloadDCPlugin() { } QString Update::dcVersion(QString const &dcBinFile) { - Command c("bash"); - QStringList param; + QProcess p; + QStringList params; - param << "-c" << QString(R"(strings %1 | grep DC2c.\[0-9\] | uniq)").arg(dcBinFile); + params << "-c" << QString(R"(strings %1 | grep DC2c.\[0-9\] | uniq)").arg(dcBinFile); - if (c.execute("/tmp", param)) { - return c.getCommandResult().trimmed().split(QRegularExpression("\\s")).first(); - // qInfo() << "(" << __func__ << ":" << __LINE__ << ")" << v; - } - - return ""; + p.start("bash", params); + p.waitForFinished(); + return QString(p.readAllStandardOutput()).trimmed().split(QRegularExpression("\\s")).first(); } class hwapi; @@ -116,11 +113,14 @@ Update::Update(QString customerRepository, QString plugInDir, QString pluginName, QString workingDir, + QString psaDcDir, bool dryRun, QObject *parent, char const *serialInterface, char const *baudrate) - : QObject(parent) + : QObject(parent) { +#if 0 + , m_hw(loadDCPlugin(QDir(plugInDir), pluginName)) , m_serialInterface(serialInterface) , m_baudrate(baudrate) @@ -129,6 +129,7 @@ Update::Update(QString customerRepository, , m_branchName(branchName) , m_pluginName(pluginName) , m_workingDir(workingDir) + , m_psaDcDir(psaDcDir) , m_dryRun(dryRun) , m_sys_areDCdataValid(false) { @@ -138,6 +139,8 @@ Update::Update(QString customerRepository, // carun stoppen } +#endif + m_start = QDateTime::currentDateTime(); } Update::~Update() { @@ -163,9 +166,16 @@ Update::sendNextAddress(int bNum) const { if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) { // qDebug() << "addr-block" << bNum << "..."; while (noAnswerCount <= 250) { - m_hw->bl_sendAddress(bNum); + // TODO + // m_hw->bl_sendAddress(bNum); + QThread::msleep(100); - DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); + + // TODO + // DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); + + DownloadResult const res = DownloadResult::OK; + if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -173,7 +183,7 @@ Update::sendNextAddress(int bNum) const { return res; } } else { // res == DownloadResult::OK - qCritical() << "addr-block" << bNum << "...OK"; + qInfo() << nextTimePoint().toUtf8().constData() << "addr-block" << bNum << "...done"; return res; } } else { @@ -197,13 +207,28 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { memcpy(local, binary.constData() + bAddr, 64); local[64] = local[65] = 0x00; + QString s = nextTimePoint(); + s += " sending block "; + s += QString("%1/%2 ...done ").arg(bNum).arg(m_totalBlocks); + s += QString::number(ceil(((bNum * 100.0) / (double)m_totalBlocks))); + + qInfo() << s.toUtf8().constData(); + + QThread::msleep(200); + return DownloadResult::OK; + // QByteArray b((const char *)(&local[0]), 64); // qCritical() << "SNDB" << bNum << b.size() << b.toHex(); while (noAnswerCount <= 250) { - m_hw->bl_sendDataBlock(64, local); - QThread::msleep(10); - DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); + // TODO + // m_hw->bl_sendDataBlock(64, local); + + // TODO + // DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); + + DownloadResult const res = DownloadResult::OK; + if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -211,7 +236,8 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { return res; } } else { - qCritical() << "data for block" << bNum << "OK"; + qInfo() << nextTimePoint().toUtf8().constData() << "data for block" + << QString("%1/%2").arg(bNum).arg(m_totalBlocks) << "done"; return res; } } else { @@ -223,7 +249,11 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { } bool Update::startBootloader() const { - qDebug() << "starting bootloader..."; + QThread::msleep(1000); + qInfo() << nextTimePoint().toUtf8().constData() << "starting bootloader ...done"; + return true; + +#if 0 int nTry = 5; while (--nTry >= 0) { m_hw->bl_startBL(); @@ -239,9 +269,15 @@ bool Update::startBootloader() const { } qCritical() << "starting bootloader...FAILED"; return false; +#endif } bool Update::stopBootloader() const { + QThread::msleep(1000); + qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader ...done"; + return true; + +#if 0 qDebug() << "stopping bootloader..."; int nTry = 5; while (--nTry >= 0) { @@ -254,21 +290,24 @@ bool Update::stopBootloader() const { } qCritical() << "stopping bootloader...FAILED"; return false; +#endif } bool Update::resetDeviceController() const { - qDebug() << "resetting device controller..."; - m_hw->bl_rebootDC(); + // TODO + // m_hw->bl_rebootDC(); + // wait maximally 3 seconds, before starting bootloader QThread::sleep(1); - qInfo() << "resetting device controller...OK"; + + qInfo() << nextTimePoint().toUtf8().constData() + << "resetting device controller ...done"; + return true; } QByteArray Update::loadBinaryDCFile(QString const &filename) const { - qCritical() << "(" << __func__ << ":" << __LINE__ << ")" - << "loading dc binary" << filename << "..."; QFile file(filename); // closed in destructor call if (!file.exists()) { @@ -281,8 +320,9 @@ QByteArray Update::loadBinaryDCFile(QString const &filename) const { << "cannot open file" << file.fileName(); return QByteArray(); } - qCritical() << "(" << __func__ << ":" << __LINE__ << ")" - << "loading dc binary" << filename << "...OK"; + + qInfo() << nextTimePoint().toUtf8().constData() + << "loading dc binary to memory" << Update::dcVersion(filename) << "...done"; return file.readAll(); } @@ -368,42 +408,46 @@ QByteArray Update::loadBinaryDCFile(QString const &filename) const { // There is no problem to repeat this command until the // bootloader is really not running anymore. */ -bool Update::doUpdate() { +bool Update::doUpdate(QString const &dcFileName) { + qInfo() << "" << Update::dcVersion(dcFileName); + + m_dcFileName = dcFileName; + //QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed()) //: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed()); - if (!m_hw) { - qCritical() << "(" << __func__ << ":" << __LINE__ << "):" - << "ERROR!!! m_hw == nullptr"; - return false; - } + //if (!m_hw) { + // qCritical() << "(" << __func__ << ":" << __LINE__ << "):" + // << "ERROR!!! m_hw == nullptr"; + // return false; + //} - QByteArray ba = loadBinaryDCFile(m_hw->dcDownloadFileName()); + QByteArray ba = loadBinaryDCFile(m_dcFileName); if (ba.size() > 0) { - uint16_t const totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1; - m_hw->dcDownloadSetTotalBlockNumber(totalBlocks); + m_totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1; + + qInfo() << nextTimePoint().toUtf8().constData() << "blocks to send" << m_totalBlocks; // fill last block of data to be sent with 0xFF - ba = ba.leftJustified(totalBlocks*64, (char)(0xFF)); + ba = ba.leftJustified(m_totalBlocks*64, (char)(0xFF)); resetDeviceController(); if (startBootloader()) { - - qCritical() << "DownloadThread::run(): TOTAL NUMBER OF BYTES TO SEND TO DC" << ba.size(); - qCritical() << "DownloadThread::run(): TOTAL NUMBER OF BLOCKS" << totalBlocks; - int currentBlock = 0; DownloadResult res = DownloadResult::OK; - qCritical() << "64-byte block " << currentBlock; - while (res != DownloadResult::ERROR && currentBlock < totalBlocks) { + qInfo() << nextTimePoint().toUtf8().constData() << "64-byte block" << currentBlock; + + while (res != DownloadResult::ERROR && currentBlock < m_totalBlocks) { if ((res = sendNextAddress(currentBlock)) != DownloadResult::ERROR) { if ((res = sendNextDataBlock(ba, currentBlock)) != DownloadResult::ERROR) { - m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); + // TODO + // m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); currentBlock += 1; - } + } else break; } } +#if 0 qCritical() << "DownloadThread::run(): last 64-byte block %04d" << currentBlock; int const rest = ba.size() % 64; @@ -422,10 +466,15 @@ bool Update::doUpdate() { m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); } qCritical() << "DownloadThread::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK()); +#endif } stopBootloader(); // there is no harm in stopping the bootloader even + // if starting the bootloader failed + qInfo() << nextTimePoint().toUtf8().constData() << ""; + return true; } + qInfo() << nextTimePoint().toUtf8().constData() << ""; return false; } diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index e253b59..96ac8a7 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include @@ -30,12 +32,20 @@ class Update : public QObject { QString m_branchName; QString m_pluginName; QString m_workingDir; + QString m_psaDcDir; + QString m_dcFileName; bool m_maintenanceMode; bool m_dryRun; bool m_sys_areDCdataValid; static QPluginLoader pluginLoader; + QDateTime m_start; + QString nextTimePoint() const { + float const secs = m_start.msecsTo(QDateTime::currentDateTime()) / 1000.0; + return QStringLiteral("+%1s").arg(secs, 7, 'f', 2, QChar('0')); + } + public: enum class DownloadResult {OK, ERROR, TIMEOUT, NOP}; enum class FileTypeJson {CONFIG=1, DEVICE=2, CASH=3, SERIAL=4, TIME=5, PRINTER=6}; @@ -44,13 +54,13 @@ public: static bool unloadDCPlugin(); static QStringList split(QString line, QChar sep = ','); - explicit Update(QString customerRepository, QString customerNrStr, QString branchName, QString plugInDir, QString pluginName, QString workingDir, + QString psaDcDir, bool dryRun = false, QObject *parent = nullptr, char const *serialInterface = SERIAL_PORT, @@ -58,7 +68,7 @@ public: virtual ~Update() override; - bool doUpdate(); + bool doUpdate(QString const &dcFileName); static QString dcVersion(QString const &dcBinFile); private: @@ -72,7 +82,7 @@ private: DownloadResult dcDownloadBinary(QByteArray const &b) const; QString m_fileToDownload; - + uint16_t m_totalBlocks = 0; /* private: static QString jsonType(enum FileTypeJson type); diff --git a/UpdatePTUDevCtrl/commandline_parser.cpp b/UpdatePTUDevCtrl/commandline_parser.cpp index 9c99a6e..67613d7 100644 --- a/UpdatePTUDevCtrl/commandline_parser.cpp +++ b/UpdatePTUDevCtrl/commandline_parser.cpp @@ -324,9 +324,9 @@ bool CommandLineParser::extendedVersion() { bool CommandLineParser::alwaysDownloadConfig() { if (m_parser.isSet(m_alwaysDownloadConfigOption)) { m_alwaysDownloadConfig = m_parser.value(m_alwaysDownloadConfigOption); - qCritical() << "m_alwaysDownloadConfigOption IS SET" << m_alwaysDownloadConfig; + // qCritical() << "m_alwaysDownloadConfigOption IS SET" << m_alwaysDownloadConfig; } - qCritical() << "m_alwaysDownloadConfig" << m_alwaysDownloadConfig; + // qCritical() << "m_alwaysDownloadConfig" << m_alwaysDownloadConfig; return m_alwaysDownloadConfig == "false" ? false : true; } diff --git a/UpdatePTUDevCtrl/git/git_client.cpp b/UpdatePTUDevCtrl/git/git_client.cpp index e194ad6..4f433d6 100644 --- a/UpdatePTUDevCtrl/git/git_client.cpp +++ b/UpdatePTUDevCtrl/git/git_client.cpp @@ -2,6 +2,7 @@ #include "update.h" #include "worker.h" #include "utils.h" +#include "process/command.h" #include #include diff --git a/UpdatePTUDevCtrl/git/git_client.h b/UpdatePTUDevCtrl/git/git_client.h index 31e5001..d7000e3 100644 --- a/UpdatePTUDevCtrl/git/git_client.h +++ b/UpdatePTUDevCtrl/git/git_client.h @@ -4,8 +4,8 @@ #include #include #include +#include -#include "process/command.h" #include "ismas/ismas_client.h" class Worker; diff --git a/UpdatePTUDevCtrl/main.cpp b/UpdatePTUDevCtrl/main.cpp index c3e8cba..c8f4770 100644 --- a/UpdatePTUDevCtrl/main.cpp +++ b/UpdatePTUDevCtrl/main.cpp @@ -31,6 +31,7 @@ #include "worker.h" #include "mainwindow.h" #include "utils.h" +// #include "process/command.h" #include #include @@ -199,5 +200,9 @@ int main(int argc, char *argv[]) { mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint); mw.showFullScreen(); + // test + worker.dcUpdate(); + // worker.summary(); + return a.exec(); } diff --git a/UpdatePTUDevCtrl/mainwindow.cpp b/UpdatePTUDevCtrl/mainwindow.cpp index 1d69513..7fe8487 100644 --- a/UpdatePTUDevCtrl/mainwindow.cpp +++ b/UpdatePTUDevCtrl/mainwindow.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -24,17 +26,22 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) , m_progressRunning(false) , m_updateStep(UpdateDcEvent::UpdateStep::NONE) { + ui->setupUi(this); + this->setStatusBar(new QStatusBar(this)); QFont f; f.setStyleHint(QFont::Monospace); f.setWeight(QFont::Bold); f.setFamily("Misc Fixed"); - f.setPixelSize(12); + f.setPointSize(11); this->statusBar()->setFont(f); +<<<<<<< HEAD ui->setupUi(this); checkOrientation(); +======= +>>>>>>> 7bfb7f5... save for christmas ui->updateProgress->setRange(0, 100); ui->updateProgress->reset(); @@ -42,15 +49,15 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) QString start = QDateTime::currentDateTime().toString(Qt::ISODate); lst << QString("Start: ") + start.leftJustified(m_width-10); lst << QString("").leftJustified(m_width-3, '='); - lst << QString("Update tool version: %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).leftJustified(m_width-3); - lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3); - lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3); - lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3); - lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3); + lst << QString("Update tool version : %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).leftJustified(m_width-3); + lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3); + lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3); + lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3); + lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3); lst << QString("").leftJustified(m_width-3, '='); - ui->updateStatus->setText(lst.join('\n')); - ui->updateStatus->setEnabled(true); + ui->updateLabel->setText(lst.join('\n')); + ui->updateLabel->setEnabled(true); // ui->updateStatus->installEventFilter(this); m_startTimer = new QTimer(this); @@ -82,11 +89,15 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) } connect(ui->exit, SIGNAL(clicked()),this,SLOT(onQuit())); + connect(m_worker, SIGNAL(showSummary(QString)),this,SLOT(onShowSummary(QString))); connect(m_worker, SIGNAL(disableExit()),this,SLOT(onDisableExit())); + connect(m_worker, SIGNAL(showDcDownload(QString)),this,SLOT(onShowDcDownload(QString))); + connect(m_worker, SIGNAL(setDcDownloadProgress(int)),this,SLOT(onSetDcDownloadProgress(int))); connect(m_worker, SIGNAL(enableExit()),this,SLOT(onEnableExit())); connect(m_worker, SIGNAL(stopStartTimer()),this,SLOT(onStopStartTimer())); connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer())); connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString))); + connect(m_worker, SIGNAL(insertText(QString)),this,SLOT(onInsertText(QString)), Qt::DirectConnection); connect(m_worker, SIGNAL(showErrorMessage(QString,QString)),this, SLOT(onShowErrorMessage(QString,QString))); connect(m_worker, SIGNAL(showStatusMessage(QString,QString)),this, SLOT(onShowStatusMessage(QString,QString))); connect(m_worker, SIGNAL(showErrorMessage(QStringList)),this, SLOT(onShowErrorMessage(QStringList))); @@ -95,6 +106,29 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString))); } + +void MainWindow::onShowSummary(QString text) { + // QString s = ui->updateLabel->text(); + QString s("\n"); + + ui->updateLabel->setText(s); + ui->updateLabel->hide(); + ui->stepLabel->hide(); + + s += text; + ui->updateStatus->setText(s); +} + +void MainWindow::onSetDcDownloadProgress(int v) { + ui->updateProgress->setValue(v); +} + +void MainWindow::onShowDcDownload(QString version) { + m_targetDcVersion = version; + ui->exit->setEnabled(false); + ui->stepLabel->setText(QString("Device controller update. Target version: %1").arg(version).leftJustified(m_width-3)); +} + MainWindow::~MainWindow() { delete m_startTimer; delete m_exitTimer; @@ -253,6 +287,12 @@ void MainWindow::scrollDownTextEdit() { ui->updateStatus->ensureCursorVisible(); } + +void MainWindow::onInsertText(QString text) { + scrollDownTextEdit(); + ui->updateStatus->textCursor().insertText(text); +} + void MainWindow::onAppendText(QString text, QString suffix) { // Utils::printInfoMsg(QString("ON APPEND CALLED AT ") // + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); diff --git a/UpdatePTUDevCtrl/mainwindow.h b/UpdatePTUDevCtrl/mainwindow.h index 4a80d18..d128d03 100644 --- a/UpdatePTUDevCtrl/mainwindow.h +++ b/UpdatePTUDevCtrl/mainwindow.h @@ -36,8 +36,11 @@ public: UpdateDcEvent::UpdateStep updateStep() const { return m_updateStep; } void setUpdateStep(UpdateDcEvent::UpdateStep updateStep) { m_updateStep = updateStep; } + QString targetDcVersion() {return m_targetDcVersion; } + public slots: void onAppendText(QString, QString suffix = ""); + void onInsertText(QString); void onReplaceLast(QStringList, QString suffix = ""); void onReplaceLast(QString, QString suffix = ""); void onShowErrorMessage(QString, QString); @@ -48,6 +51,9 @@ public slots: void onRestartExitTimer(); void onEnableExit(); void onDisableExit(); + void onShowDcDownload(QString); + void onSetDcDownloadProgress(int); + void onShowSummary(QString); #if EMERGENCY_LEAVE_BL==1 void emergencyLeaveBL(); #endif @@ -80,5 +86,6 @@ private: //int m_progressValue; UpdateDcEvent::UpdateStep m_updateStep; QTimer *m_statusTimer; + QString m_targetDcVersion; }; #endif // MAINWINDOW_H diff --git a/UpdatePTUDevCtrl/mainwindow.ui b/UpdatePTUDevCtrl/mainwindow.ui index 82fa12e..f88b4c1 100644 --- a/UpdatePTUDevCtrl/mainwindow.ui +++ b/UpdatePTUDevCtrl/mainwindow.ui @@ -18,54 +18,117 @@ - Source Code Pro + Misc Fixed + 11 + 75 + true MainWindow - - - - - - - Exit - - - - - - - 1 - - - - - - - true - - - - Misc Fixed - 11 - 75 - true - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - - - - + + + + 10 + 10 + 781 + 441 + + + + + + + + 0 + 18 + + + + + Misc Fixed + 11 + 75 + true + + + + + + + + + + + true + + + + Misc Fixed + 11 + 75 + true + + + + Qt::NoFocus + + + QFrame::WinPanel + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustToContents + + + false + + + + + + + + 0 + 100 + + + + + Misc Fixed + 11 + 75 + true + + + + + + + + + + + 1 + + + + + + + Exit + + + + + diff --git a/UpdatePTUDevCtrl/process/command.cpp b/UpdatePTUDevCtrl/process/command.cpp index ab8f40d..b0b8747 100644 --- a/UpdatePTUDevCtrl/process/command.cpp +++ b/UpdatePTUDevCtrl/process/command.cpp @@ -1,4 +1,5 @@ #include "command.h" +#include "worker.h" #include #include @@ -7,12 +8,15 @@ #include #include + Command::Command(QString const &command, int start_timeout, int finish_timeout) : m_command(command.trimmed()) , m_commandResult("") , m_waitForStartTimeout(start_timeout) , m_waitForFinishTimeout(finish_timeout) - , m_exitCode(-1) { + , m_exitCode(-1) + , m_p(nullptr) + , m_worker(nullptr) { } QString Command::getCommandResult(bool reset) const { @@ -31,13 +35,52 @@ QString Command::getCommandResult(bool reset) const { void Command::readyReadStandardOutput() { QMutexLocker locker(&m_mtx); QProcess *p = (QProcess *)sender(); - m_commandResult += p->readAllStandardOutput(); + if (p) { + QString s = p->readAllStandardOutput(); + if (m_worker) { + int i = -1; + if ((i = s.indexOf("")) != -1) { + s = s.mid(i+12).trimmed(); + if ((i = s.indexOf("\"")) != -1) { + s = s.mid(i+1); + if ((i = s.indexOf("\"")) != -1) { + s = s.mid(0, i).trimmed(); + } + } + emit m_worker->showDcDownload(s); + } else + if ((i = s.indexOf("")) != -1) { + bool ok; + int v = s.mid(i+10).trimmed().toInt(&ok); + if (ok) { + emit m_worker->setDcDownloadProgress(v); + emit m_worker->insertText(s.mid(0,i) + "\n"); + } + } else + if ((i = s.indexOf("")) != -1) { + m_worker->summary(); + // qApp->exit(0); + } else + if ((i = s.indexOf("")) != -1) { + m_worker->summary(); + } else + if ((i = s.indexOf("")) != -1) { + m_worker->summary(); + //qApp->exit(-1); + } else { + emit m_worker->insertText(s); + } + } + m_commandResult += s; + } } void Command::readyReadStandardError() { QProcess *p = (QProcess *)sender(); - QByteArray buf = p->readAllStandardError(); - qCritical() << buf; + if (p) { + QByteArray buf = p->readAllStandardError(); + qCritical() << buf; + } } void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) { @@ -52,6 +95,31 @@ void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) { disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError())); } +bool Command::start(QString workingDirectory, QStringList args) { + if (!QDir::setCurrent(workingDirectory)) { + qCritical() << "SET WORKING_DIRECTORY" << workingDirectory + << "FAILED FOR" << m_command; + return false; + } + if (m_p != nullptr) { + delete m_p; + } + m_p = new QProcess(this); + m_p->setWorkingDirectory(workingDirectory); + m_p->setProcessChannelMode(QProcess::MergedChannels); + + connect(m_p, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput())); + connect(m_p, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError())); + + if (!args.isEmpty()) { + m_p->start(m_command, args); + } else { + m_p->start(m_command); + } + + return m_p->waitForStarted(m_waitForStartTimeout); +} + bool Command::execute(QString workingDirectory, QStringList args) { if (!QDir::setCurrent(workingDirectory)) { diff --git a/UpdatePTUDevCtrl/process/command.h b/UpdatePTUDevCtrl/process/command.h index 460f935..71efb22 100644 --- a/UpdatePTUDevCtrl/process/command.h +++ b/UpdatePTUDevCtrl/process/command.h @@ -9,7 +9,7 @@ #include #include - +class Worker; class Command : public QObject { Q_OBJECT @@ -19,6 +19,8 @@ class Command : public QObject { int m_waitForFinishTimeout; int m_exitCode; mutable QMutex m_mtx; + QProcess *m_p; + Worker *m_worker; public: explicit Command(QString const &command, int start_timeout = 100000, @@ -28,8 +30,11 @@ public: QString command() const { return m_command; } bool execute(QString workingDirectory, QStringList args = QStringList()); + bool start(QString workingDirectory, QStringList args = QStringList()); int exitCode() const { return m_exitCode; } + void setWorker(Worker *worker) {m_worker = worker; } + private slots: void readyReadStandardOutput(); void readyReadStandardError(); diff --git a/UpdatePTUDevCtrl/utils.cpp b/UpdatePTUDevCtrl/utils.cpp index 010b838..7b7ec65 100644 --- a/UpdatePTUDevCtrl/utils.cpp +++ b/UpdatePTUDevCtrl/utils.cpp @@ -13,9 +13,65 @@ #include #include #include +#include +#include +#include +#include +#include #include +QVector> Utils::installedPackages() { + QVector> vec; + if (QFile::exists("/usr/bin/ptuPackageVersions")) { + QProcess p; + QStringList params; + params << "-c" << R"(/usr/bin/ptuPackageVersions -i -o json)"; + + p.start("bash", params); + p.waitForFinished(); + + QString r = p.readAllStandardOutput(); + + // ptuPackageVersions returns a json-array + QJsonArray const &ja = QJsonDocument::fromJson(r.remove(QRegExp("\\n")).toUtf8()).array(); + if (!ja.empty()) { + qCritical() << __LINE__; + // transform the array into an object, containing the objects + // of the array (christian needs it this way) + foreach (QJsonValue const &value, ja) { + if (value.isObject()) { + QJsonObject obj = value.toObject(); + QStringList keys = obj.keys(); + if (!keys.isEmpty()) { + QString const &k = keys.first(); + QJsonValue const &v = obj.value(k); + if (v.isObject()) { + obj = v.toObject(); + if (obj.keys().contains("Version")) { + QJsonValue const &w = obj.value("Version"); + if (w.isString()) { + QString s = w.toString(); + QPair p(k, s); + vec.push_back(p); + } + } + } + } + } + } + } else { + qCritical() << __func__ << ":" << __LINE__ + << "ERROR array return by ptuPackageVersions empty"; + } + } else { + qCritical() << __func__ << ":" << __LINE__ + << "ERROR executing ptuPackageVersions"; + } + + return vec; +} + int Utils::read1stLineOfFile(QString fileName) { QFile f(fileName); if (f.exists()) { diff --git a/UpdatePTUDevCtrl/utils.h b/UpdatePTUDevCtrl/utils.h index 8fdd648..a5c93c1 100644 --- a/UpdatePTUDevCtrl/utils.h +++ b/UpdatePTUDevCtrl/utils.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace Utils { int read1stLineOfFile(QString fileName); @@ -33,6 +34,8 @@ namespace Utils { QString getParentName(); bool isATBQTRunning(); + + QVector> installedPackages(); } #endif // UTILS_H_INCLUDED diff --git a/UpdatePTUDevCtrl/worker.cpp b/UpdatePTUDevCtrl/worker.cpp index 8c1a12a..4cddd9d 100644 --- a/UpdatePTUDevCtrl/worker.cpp +++ b/UpdatePTUDevCtrl/worker.cpp @@ -26,6 +26,7 @@ #include "progress_event.h" #include "mainwindow.h" #include "utils.h" +#include "process/command.h" QString const Worker::UPDATE_STEP_OK ( " [ ok]"); QString const Worker::UPDATE_STEP_DONE ( " [done]"); @@ -176,9 +177,14 @@ Worker::Worker(int customerNr, , m_filesToUpdate() , m_updateProcessRunning(true) , m_mainWindow(nullptr) /* contains plugin */ + , m_dcDownloadFirmware(new Command("/opt/app/tools/atbupdate/ATBDownloadDCFirmware --read-dc-version true")) //, m_withoutIsmasDirectPort(true) /* useful for testing */ { , m_withoutIsmasDirectPort(false) /* useful for testing */ { + + m_start = QDateTime::currentDateTime(); + m_dcDownloadFirmware->setWorker(this); + // TODO: turn object into singleton instance = this; m_lastFailedUpdateStep = UPDATE_STEP::NONE; @@ -284,6 +290,8 @@ void Worker::privateUpdate() { return; } + return; + QString func(__PRETTY_FUNCTION__); GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::STARTED)); @@ -1257,6 +1265,7 @@ QString Worker::getPluginVersion(QString const &pluginFileName) const { QStringList Worker::getDCVersion() const { QStringList lst = (QStringList() << "N/A" << "N/A"); +#if 0 Update const *up = update(); if (up) { hwinf const *caPlugin = up->hw(); @@ -1278,6 +1287,7 @@ QStringList Worker::getDCVersion() const { } } } +#endif return lst; } @@ -1490,3 +1500,78 @@ PSAInstalled Worker::getPSAInstalled() { return psaInstalled; } + +bool Worker::dcUpdate() { + return m_dcDownloadFirmware->start("/opt/app/tools/atbupdate"); +} + +void Worker::summary() { + + QString summary, first, second, line, tmp; + QVector> vec = Utils::installedPackages(); + + int max_first = 0, max_second = 0; + for (int i = 0; i < vec.size(); ++i) { + max_first = std::max(max_first, vec[i].first.length()); + max_second = std::max(max_second, vec[i].second.length()); + } + + max_first += 5; + + summary = "UPDATE SUMMARY\n\n"; + + first = QString("%1").arg("start", max_first, QChar(' ')); + tmp = QString("%1").arg(start().toString(Qt::ISODate)); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + first = QString("%1").arg("update tool version", max_first, QChar(' ')); + tmp = QString("%1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + first = QString("%1").arg("machine number", max_first, QChar(' ')); + tmp = QString("%1").arg(machineNr()); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + first = QString("%1").arg("customer number", max_first, QChar(' ')); + tmp = QString("%1").arg(customerNr()); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + first = QString("%1").arg("zone number", max_first, QChar(' ')); + tmp = QString("%1").arg(zoneNr()); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + if (m_mainWindow) { + tmp = m_mainWindow->targetDcVersion(); + if (!tmp.isEmpty()) { + first = QString("%1").arg("target device controller", max_first, QChar(' ')); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + } + } + + first = QString("%1").arg("apism", max_first, QChar(' ')); + tmp = QString("%1").arg(apismVersion()); + second = QString("%1").arg(tmp, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + + for (int i = 0; i < vec.size(); ++i) { + first = QString("%1").arg(vec[i].first, max_first, QChar(' ')); + second = QString("%1").arg(vec[i].second, -max_second, QChar(' ')); + line = first + ": " + second; + summary += line + "\n"; + } + + emit showSummary(summary); +} diff --git a/UpdatePTUDevCtrl/worker.h b/UpdatePTUDevCtrl/worker.h index d30984d..8c54d69 100644 --- a/UpdatePTUDevCtrl/worker.h +++ b/UpdatePTUDevCtrl/worker.h @@ -15,7 +15,6 @@ #include #include -#include "update.h" #include "git/git_client.h" #include "ismas/ismas_client.h" #include "utils.h" @@ -135,6 +134,8 @@ #define ISMAS_UPDATE_REQUESTS (10) #define CHECK_UPDATE_TRIGGER_SET "Check update trigger ..." +class Command; +class Update; class MainWindow; class hwinf; class Worker : public QThread{ @@ -189,6 +190,7 @@ class Worker : public QThread{ QStringList m_ismasTriggerStatusMessage; MainWindow *m_mainWindow; + Command *m_dcDownloadFirmware; bool m_withoutIsmasDirectPort; QString m_apismVersion; @@ -458,8 +460,13 @@ public: Update *update() { return m_update; } Update const *update() const { return m_update; } + bool dcUpdate(); + void summary(); + QDateTime start() { return m_start; } + signals: void appendText(QString, QString suffix = ""); + void insertText(QString); void replaceLast(QString, QString); void replaceLast(QStringList, QString); void showErrorMessage(QString title, QString description); @@ -470,6 +477,9 @@ signals: void restartExitTimer(); void enableExit(); void disableExit(); + void showDcDownload(QString); + void showSummary(QString); + void setDcDownloadProgress(int); private slots: bool updateTriggerSet(); @@ -487,6 +497,8 @@ private: bool computeFilesToDownload(); bool execOpkgCommands(); + QDateTime m_start; + static const QMap smap; // CONSOLE() diff --git a/common/include/System.h b/common/include/System.h index 4c59a04..18c0a45 100644 --- a/common/include/System.h +++ b/common/include/System.h @@ -25,7 +25,9 @@ public: static bool umountSDCard(); static std::optional checkForUSBStick(QString const &dirPathUnderMountPath = "."); + static std::optional checkForSDCard(QString const &dirPathUnderMountPath = "."); static QString getUSBMountPath(QString const &dirPathUnderMountPath = "."); + static QString getSDMountPath(QString const &dirPathUnderMountPath = "."); //static QString getUSBDeviceName(); static bool umountUSBStick(); @@ -54,7 +56,8 @@ public: static QString getPTU4MACAddress(); static QStringList getJsonFilesOnUsbStick(QString const &mountPath); - + static QString getDCFileOnUsbStick(QString const &mountPath); + static QString getDCFileOnSDCard(QString const &mountPath); }; #endif // SYSTEM_H diff --git a/common/src/System.cpp b/common/src/System.cpp index 72358e2..2af9af8 100644 --- a/common/src/System.cpp +++ b/common/src/System.cpp @@ -265,6 +265,20 @@ std::optional System::checkForUSBStick(QString const &dirPathUnderMount return mountPath.isEmpty() ? std::nullopt : std::optional(mountPath); } +std::optional System::checkForSDCard(QString const &dirPathUnderMountPath) { +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + if (QFileInfo(getSDMountPath()).isDir()) + return true; + else + return false; +#endif + + QString const &mountPath = getSDMountPath(dirPathUnderMountPath); + // qCritical() << "MOUNT-PATH" << mountPath; + return mountPath.isEmpty() ? std::nullopt : std::optional(mountPath); +} + /** @@ -315,7 +329,7 @@ QString System::getUSBMountPath(QString const &dirPathUnderMountPath) { mountLine = line.split(' '); if (mountLine.size() > 3) { - qCritical() << "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); @@ -332,6 +346,64 @@ QString System::getUSBMountPath(QString const &dirPathUnderMountPath) { return ""; } +QString System::getSDMountPath(QString const &dirPathUnderMountPath) { + +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return QDir::homePath().append("/APconfigTest/USB"); +#endif + + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + QStringList mountLine; + + qDebug() << "System::getSDMountPath()"; + + QRegExp devRegExp = QRegExp("dev/mmc*", Qt::CaseSensitive, QRegExp::WildcardUnix); + QRegExp mountRegExp = QRegExp("media/mmc*", Qt::CaseSensitive, QRegExp::WildcardUnix); + + QString commandString = "mount"; + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::getSDMountPath(): ERROR: waitForStarted()"; + return ""; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::getSDMountPath(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return ""; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + qDebug() << "System::getSDMountPath() line: " << line; + + if (line.contains(devRegExp) && line.contains(mountRegExp)) { + + qDebug() << " -> this line is a usb storage device mount" << line; + + mountLine = line.split(' '); + if (mountLine.size() > 3) { + // qCritical() << "System::getSDMountPath(): " << 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"; + } + } + } + } + } + + qDebug() << "System::getSDMountPath() no mounted usb device found!"; + + return ""; +} + QStringList System::getJsonFilesOnUsbStick(QString const &mountPath) { QStringList jsonFiles; @@ -354,6 +426,38 @@ QStringList System::getJsonFilesOnUsbStick(QString const &mountPath) { return jsonFiles; } +QString System::getDCFileOnUsbStick(QString const &mountPath) { + QString dcFile; + + // /media/sda2/etc/dc + QString const &dirPath = QDir::cleanPath(mountPath + QDir::separator() + "etc" + QDir::separator() + "dc"); + QDir d(dirPath); + if (d.exists()) { + QFileInfo fi(dirPath + QDir::separator() + "dc2c.bin"); + if (fi.exists()) { + dcFile = fi.absoluteFilePath(); + } + } + + return dcFile; +} + +QString System::getDCFileOnSDCard(QString const &mountPath) { + QString dcFile; + + // /media/sda2/etc/dc + QString const &dirPath = QDir::cleanPath(mountPath + QDir::separator() + "etc" + QDir::separator() + "dc"); + QDir d(dirPath); + if (d.exists()) { + QFileInfo fi(dirPath + QDir::separator() + "dc2c.bin"); + if (fi.exists()) { + dcFile = fi.absoluteFilePath(); + } + } + + return dcFile; +} + /******************************************************************************** * static function to check if a mounted sd-card is writable. * From d2d0eb40aa414ea5397066eca05f201ed134090c Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 10:26:56 +0100 Subject: [PATCH 10/39] Revert "Remove any reference to device controller as downloading jsons/dc-firmware" This reverts commit 6b0a784fc8152ebdaea348209538b884add9e78b. --- UpdatePTUDevCtrl/update.cpp | 155 ++++++++++++++++++++++++++++++++---- UpdatePTUDevCtrl/update.h | 7 ++ 2 files changed, 147 insertions(+), 15 deletions(-) diff --git a/UpdatePTUDevCtrl/update.cpp b/UpdatePTUDevCtrl/update.cpp index 29dcd10..837e467 100644 --- a/UpdatePTUDevCtrl/update.cpp +++ b/UpdatePTUDevCtrl/update.cpp @@ -105,6 +105,7 @@ Update::Update(Worker *worker, char const *serialInterface, char const *baudrate) : QObject(parent) + , m_hw(loadDCPlugin(QDir(plugInDir), pluginName)) , m_worker(worker) , m_serialInterface(serialInterface) , m_baudrate(baudrate) @@ -115,6 +116,24 @@ Update::Update(Worker *worker, , m_workingDir(workingDir) , m_dryRun(dryRun) , m_sys_areDCdataValid(false) { + + if (!m_hw) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_hw == nullptr -> ca-slave plugin not 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() { @@ -132,6 +151,43 @@ void Update::onReportDCDownloadFailure(QString const &errorMsg) { qCritical() << "msg" << errorMsg; } + + +// br is a index into a table, used for historical reasons. +bool Update::openSerial(int br, QString baudrate, QString comPort) const { + if (m_hw) { + qDebug() << "opening serial" << br << baudrate << comPort << "..."; + if (m_hw->dc_openSerial(br, baudrate, comPort, 1) == true) { // 1 for connect + Utils::printInfoMsg( + QString("OPENING SERIAL %1").arg(br) + + " " + baudrate + " " + comPort + "...OK"); + + // m_hw->dc_autoRequest(true); + // m_hw->dc_autoRequest(false); + // QThread::sleep(1); + + Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen())); + return true; + } + + Utils::printCriticalErrorMsg( + QString("OPENING SERIAL %1").arg(br) + + " " + baudrate + " " + comPort + "...FAILED"); + } + return false; +} + +void Update::closeSerial() const { + qInfo() << "CLOSED SERIAL" << m_baudrate << m_serialInterface; + if (m_hw) { + m_hw->dc_closeSerial(); + } +} + +bool Update::isSerialOpen() const { + return m_hw ? m_hw->dc_isPortOpen() : false; +} + /* /////////////////////////////////////////////////////////////////////////////// @@ -226,13 +282,95 @@ bool Update::updateBinary(QString const &fileToSendToDC) { qInfo() << "updating dc-binary" << fileToSendToDC << "..."; return false; + +#if 0 + QFile fn(fileToSendToDC); + if (!fn.exists()) { + // output via CONSOLE() etc + return false; + } + + bool bl_isUp = false; + if (m_hw->bl_completeStart()) { + int cnt = 5; + while (--cnt > 0) { + if (m_hw->bl_isUp()) { + bl_isUp = true; + break; + } + } + } + + if (!bl_isUp) { + return false; + } + + if (!m_hw->bl_storeFirmware(fileToSendToDC)) { + m_hw->bl_stopBL(); + return false; + } + + uint16_t const nrOfFirmwareBlocks = m_hw->bl_getNrOfFirmwareBlocks(); + + for (uint16_t blockNr = 0; blockNr <= nrOfFirmwareBlocks; ++blockNr) { + m_hw->bl_blockAutoLoad(blockNr); + + int sleepTime = 0; + while (1) { + if (sleepTime > 1500) { + m_hw->bl_stopBL(); + return false; + } + + int8_t const r = m_hw->bl_blockAutoResponse(); + + // after every "bl_blockAutoLoad()" call this until response + // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete + // 3: error despite repeating, cancel. probably bin file corrupted + // Max duration: 3x no response from BL = 900ms + + switch(r) { + case 1: + /* fall through */ + case 2: + sleepTime = 0; + break; + case 0: { + QThread::msleep(100); + sleepTime += 100; + } break; + case 3: + m_hw->bl_stopBL(); + return false; + default: + m_hw->bl_stopBL(); + return false; // unknown error code + } + } + + m_hw->bl_stopBL(); + } + + return true; +#endif +} + +QString Update::jsonType(enum FileTypeJson type) { + switch (type) { + case FileTypeJson::CASH: return "CASH"; + case FileTypeJson::CONFIG: return "CONFIG"; + case FileTypeJson::PRINTER: return "PRINTER"; + case FileTypeJson::SERIAL: return "SERIAL"; + case FileTypeJson::DEVICE: return "DEVICE"; + case FileTypeJson::TIME: return "TIME"; + } + return "N/A"; } bool Update::downloadJson(enum FileTypeJson type, int templateIdx, QString jsFileToSendToDC) const { -#if 0 if (m_hw) { m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag qDebug() << "SET AUTO-REQUEST=TRUE"; @@ -351,7 +489,6 @@ bool Update::downloadJson(enum FileTypeJson type, // QThread::sleep(1); // make sure the auto-request flag is acknowledged } -#endif return true; } @@ -410,7 +547,6 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) { } QStringList Update::getDcSoftAndHardWareVersion() { -#if 0 if (m_hw) { m_hw->dc_autoRequest(true); QThread::sleep(1); // make sure the timer-slots are active @@ -433,17 +569,15 @@ QStringList Update::getDcSoftAndHardWareVersion() { } } -#endif return QStringList() << "DC HW-version not available" << "DC SW-version not available"; } QString Update::getFileVersion(QString const& jsonFileName) { - QString fileVersion(""); -#if 0 // "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()) { @@ -468,12 +602,10 @@ QString Update::getFileVersion(QString const& jsonFileName) { // qCritical() << "ERROR" << inputFile.fileName() << "does not exist"; } -#endif return fileVersion; } bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) { -#if 0 for (QStringList::size_type i=0; i < jsonFileNames.size(); ++i) { @@ -548,7 +680,6 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) { } } -#endif return false; } @@ -556,7 +687,6 @@ QMap Update::getInstalledJsonVersions(QStringList const& jsonFileNames) { QMap map; -#if 0 if (!m_hw) { qCritical() << "(" << __func__ << ":" << __LINE__ << "):" << "ERROR!!! m_hw == nullptr"; @@ -656,13 +786,11 @@ Update::getInstalledJsonVersions(QStringList const& jsonFileNames) { } } -#endif return map; } bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) { -#if 0 if (!m_hw) { Utils::printInfoMsg("CA-PLUGIN NOT LOADED"); return false; @@ -869,7 +997,4 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) { qDebug() << "SET AUTO-REQUEST=TRUE"; return res; -#endif - - return false; } diff --git a/UpdatePTUDevCtrl/update.h b/UpdatePTUDevCtrl/update.h index 4abdd28..b70c02a 100644 --- a/UpdatePTUDevCtrl/update.h +++ b/UpdatePTUDevCtrl/update.h @@ -22,6 +22,7 @@ class Worker; class Update : public QObject { Q_OBJECT + hwinf *m_hw = nullptr; Worker *m_worker = nullptr; char const *m_serialInterface; char const *m_baudrate; @@ -101,6 +102,12 @@ public: 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; } + + //QString customerId() { return m_customerId; } + //QString const customerId() const { return m_customerId; } + QString branchName() { return m_branchName; } QString const branchName() const { return m_branchName; } From d85eabf3e6dd1f33a3854d75f3e6f3cb9e0999f6 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 11:05:22 +0100 Subject: [PATCH 11/39] save files with comment (was 8f822c5) --- DownloadDCFirmware/update.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index dafbc1b..2e7af00 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -209,7 +209,7 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { QString s = nextTimePoint(); s += " sending block "; - s += QString("%1/%2 ...done ").arg(bNum).arg(m_totalBlocks); + s += QString("%1/%2 ...done ").arg(bNum).arg(m_totalBlocks); s += QString::number(ceil(((bNum * 100.0) / (double)m_totalBlocks))); qInfo() << s.toUtf8().constData(); From 724be1568d7b9378a76d85ed349e46aee6e17625 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 26 Feb 2025 16:55:40 +0100 Subject: [PATCH 12/39] remove main-window (not needed) --- DownloadDCFirmware/DownloadDCFirmware.pro | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/DownloadDCFirmware/DownloadDCFirmware.pro b/DownloadDCFirmware/DownloadDCFirmware.pro index 088f6d1..98a8a9c 100644 --- a/DownloadDCFirmware/DownloadDCFirmware.pro +++ b/DownloadDCFirmware/DownloadDCFirmware.pro @@ -1,7 +1,6 @@ -QT += core gui -QT += widgets serialport network +QT += core serialport -TARGET = ATBDownloadDCFirmware +TARGET = ATBUpdateDC VERSION="0.1.0" win32 { @@ -77,21 +76,23 @@ contains( CONFIG, DesktopLinux ) { SOURCES += \ main.cpp \ - mainwindow.cpp \ ../common/src/message_handler.cpp \ ../UpdatePTUDevCtrl/commandline_parser.cpp \ update.cpp \ dc_download.cpp \ - ../common/src/System.cpp + ../common/src/System.cpp \ + ../common/src/utils_internal.cpp \ + ../common/src/command.cpp HEADERS += \ - mainwindow.h \ ../common/include/message_handler.h \ ../UpdatePTUDevCtrl/commandline_parser.h \ update.h \ dc_download.h \ - ../common/include/System.h + ../common/include/System.h \ + ../common/include/utils_internal.h \ + ../common/include/command.h OTHER_FILES += \ From 6a32c75754cdfa3710fb85af9e7103ba8d071130 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 26 Feb 2025 16:56:33 +0100 Subject: [PATCH 13/39] use qcoreapplication -> no window or widgets --- DownloadDCFirmware/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 4c508fa..560c215 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -16,7 +15,6 @@ #include "commandline_parser.h" #include "utils.h" #include "update.h" -#include "mainwindow.h" #include "System.h" #include @@ -54,9 +52,9 @@ int main(int argc, char **argv) { openlog("DC", LOG_PERROR | LOG_CONS, LOG_USER); - QApplication a(argc, argv); - QApplication::setApplicationName("ATBDownloadDCFirmware"); - QApplication::setApplicationVersion(APP_VERSION); + QCoreApplication a(argc, argv); + QCoreApplication::setApplicationName("ATBDownloadDCFirmware"); + QCoreApplication::setApplicationVersion(APP_VERSION); if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling atbInstallMessageHandler(atbDebugOutput); From 579997b318bc01ad5c24eb351b192a6de4f1bc41 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 26 Feb 2025 16:57:01 +0100 Subject: [PATCH 14/39] to be removed --- DownloadDCFirmware/mainwindow.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/DownloadDCFirmware/mainwindow.h b/DownloadDCFirmware/mainwindow.h index 72a2ea1..7a76079 100644 --- a/DownloadDCFirmware/mainwindow.h +++ b/DownloadDCFirmware/mainwindow.h @@ -1,10 +1,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include #include -#include -#include #include #include From 5b621298c4fab23d9fdb6bfddabef2619ee3429f Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 26 Feb 2025 16:57:57 +0100 Subject: [PATCH 15/39] take over some code from mainwindow --- DownloadDCFirmware/update.cpp | 31 +++++++++++++++++++++++++++++++ DownloadDCFirmware/update.h | 7 +++++++ 2 files changed, 38 insertions(+) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 2e7af00..1a22343 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #define UPDATE_OPKG (1) #define UPDATE_DC (0) @@ -147,6 +149,35 @@ Update::~Update() { unloadDCPlugin(); } +bool Update::openSerialPort() { + // const SettingsDialog::Settings p = m_settings->settings(); + m_serial->setPortName(SERIAL_PORT); + m_serial->setBaudRate(QSerialPort::Baud115200); + m_serial->setDataBits(QSerialPort::DataBits::Data8); + m_serial->setParity(QSerialPort::Parity::NoParity); + m_serial->setStopBits(QSerialPort::StopBits::OneStop); + m_serial->setFlowControl(QSerialPort::FlowControl::NoFlowControl); + if (m_serial->open(QIODevice::ReadWrite)) { + //showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6") + // .arg(p.name, p.stringBaudRate, p.stringDataBits, + // p.stringParity, p.stringStopBits, p.stringFlowControl)); + return true; + } else { + //QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + //showStatusMessage(tr("Open error")); + } + return false; +} + +bool Update::closeSerialPort() { + if (m_serial->isOpen()) { + m_serial->close(); + return true; + } + return false; + //showStatusMessage(tr("Disconnected")); +} + Update::DownloadResult Update::sendStatus(int ret) const { switch (ret) { // return values of dc are: case 0: // 0: no answer by now diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index 96ac8a7..278052a 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -21,6 +21,7 @@ #define SERIAL_PORT "ttyUSB0" #endif +class QSerialPort; class Update : public QObject { Q_OBJECT @@ -46,6 +47,12 @@ class Update : public QObject { return QStringLiteral("+%1s").arg(secs, 7, 'f', 2, QChar('0')); } + + bool openSerialPort(); + bool closeSerialPort(); + + QSerialPort *m_serial; + public: enum class DownloadResult {OK, ERROR, TIMEOUT, NOP}; enum class FileTypeJson {CONFIG=1, DEVICE=2, CASH=3, SERIAL=4, TIME=5, PRINTER=6}; From eb3f05ff19460b4c997fce106f62147b26558352 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 28 Feb 2025 14:22:51 +0100 Subject: [PATCH 16/39] preparing dc-update --- DownloadDCFirmware/DownloadDCFirmware.pro | 2 - DownloadDCFirmware/update.cpp | 233 ---------------------- DownloadDCFirmware/update.h | 1 - 3 files changed, 236 deletions(-) diff --git a/DownloadDCFirmware/DownloadDCFirmware.pro b/DownloadDCFirmware/DownloadDCFirmware.pro index 98a8a9c..51f5641 100644 --- a/DownloadDCFirmware/DownloadDCFirmware.pro +++ b/DownloadDCFirmware/DownloadDCFirmware.pro @@ -79,7 +79,6 @@ SOURCES += \ ../common/src/message_handler.cpp \ ../UpdatePTUDevCtrl/commandline_parser.cpp \ update.cpp \ - dc_download.cpp \ ../common/src/System.cpp \ ../common/src/utils_internal.cpp \ ../common/src/command.cpp @@ -89,7 +88,6 @@ HEADERS += \ ../common/include/message_handler.h \ ../UpdatePTUDevCtrl/commandline_parser.h \ update.h \ - dc_download.h \ ../common/include/System.h \ ../common/include/utils_internal.h \ ../common/include/command.h diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 1a22343..76e2cf6 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -508,236 +508,3 @@ bool Update::doUpdate(QString const &dcFileName) { qInfo() << nextTimePoint().toUtf8().constData() << ""; return false; } - -#if 0 -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); -} -#endif diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index 278052a..edf0c62 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -47,7 +47,6 @@ class Update : public QObject { return QStringLiteral("+%1s").arg(secs, 7, 'f', 2, QChar('0')); } - bool openSerialPort(); bool closeSerialPort(); From 98996af2b2e8feaea80c86eb603e45037d628852 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 7 Mar 2025 12:06:03 +0100 Subject: [PATCH 17/39] read ini-file and determine device controller to install --- DownloadDCFirmware/main.cpp | 85 ++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 560c215..b9e957f 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -10,10 +10,12 @@ #include #include #include +#include #include "message_handler.h" #include "commandline_parser.h" #include "utils.h" +#include "utils_internal.h" #include "update.h" #include "System.h" @@ -53,14 +55,20 @@ int main(int argc, char **argv) { openlog("DC", LOG_PERROR | LOG_CONS, LOG_USER); QCoreApplication a(argc, argv); - QCoreApplication::setApplicationName("ATBDownloadDCFirmware"); + QCoreApplication::setOrganizationName("ATB Automatentechnik Baumann GmBH"); + QCoreApplication::setApplicationName("ATBUpdateDC"); QCoreApplication::setApplicationVersion(APP_VERSION); + if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling atbInstallMessageHandler(atbDebugOutput); setDebugLevel(LOG_NOTICE); } + + //return 0; + +/* CommandLineParser parser; parser.process(a); parser.readSettings(); @@ -125,6 +133,30 @@ int main(int argc, char **argv) { QString const &customerRepo = QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr)); +*/ + + QString const &psaDcDir = internal::customerRepoDcDir(); + QString const &psaRepoRootDir = internal::customerRepoRoot(); + QString const &psaRepoDir = internal::customerRepoDir(); + QString const &branchName = internal::branchName(); + + bool debug = false; + bool noaction = true; + QString workingDir; + QString libca; + + std::unique_ptr settings = internal::readSettings(); + if (settings) { + settings->beginGroup("COMMON"); + debug = settings->value("debug", false).toBool(); + settings->endGroup(); + + settings->beginGroup("RUNTIME"); + noaction = settings->value("noaction", true).toBool(); + workingDir = settings->value("workingdir", "/tmp").toBool(); + libca = settings->value("libca", "/usr/lib/libCAslave.so").toString(); + settings->endGroup(); + } // etc/dc: located under mount-path std::optional mountPath = System::checkForUSBStick(psaDcDir); @@ -135,47 +167,32 @@ int main(int argc, char **argv) { if ((mountPath = System::checkForSDCard(psaDcDir)).has_value()) { fi.setFile(mountPath.value(), System::getDCFileOnSDCard(mountPath.value())); } else { - qInfo() << "using customer repository" << customerRepo; - QDir dir(QDir::cleanPath(customerRepo + QDir::separator() + "etc/dc")); - if (dir.exists()) { - fi.setFile(dir, dir.absoluteFilePath("dc2c.bin")); - } else { - qCritical() << "DIRECTORY" << dir << "DOES NOT EXIST"; - return -1; + if (debug) { + qInfo() << "using customer repository" << psaRepoDir; + } + + std::unique_ptr c = internal::dcCandidateToInstall(); + if (c) { + fi.setFile(*c); + if (fi.exists() == false) { + qCritical() << "dc2c.bin candidate" << *c << "does not exist. STOP."; + return -1; + } + qInfo() << "dc2c.bin canditate" << fi.absoluteFilePath(); } } - qInfo() << "downloading dc-firmware .." << fi.absoluteFilePath(); - qInfo() << "dc-firmware size (bytes) ." << fi.size(); - if (readDCVersion) { - qInfo() << "dc-version ..............." << Update::dcVersion(fi.absoluteFilePath()); + if (debug) { + qInfo() << "downloading dc-firmware" << fi.absoluteFilePath(); + qInfo() << "dc-firmware size (bytes)" << fi.size(); + qInfo() << "dc-version" << Update::dcVersion(fi.absoluteFilePath()); } - QThread::currentThread()->setObjectName("main thread"); - // qInfo() << "Main thread" << QThread::currentThreadId(); - - Update update(customerRepo, - QString::number(customerNr), - branchName, - plugInDir, - plugInName, - workingDir, - psaDcDir); - - update.doUpdate(fi.absoluteFilePath()); - - // MainWindow mw; - - // mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint); - // mw.showFullScreen(); - - // qCritical() << "SHOW"; - - // mw.show(); + Update u(fi.absoluteFilePath(), libca, debug, noaction); + u.run(); qInfo() << ""; return 0; - // return a.exec(); } From d8112800d52927cda87dced584f4efebb65a87ca Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 7 Mar 2025 12:09:07 +0100 Subject: [PATCH 18/39] cleaning up source. rename doUndate() to run(). --- DownloadDCFirmware/update.cpp | 159 +++++++++++----------------------- DownloadDCFirmware/update.h | 42 +++------ 2 files changed, 60 insertions(+), 141 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 76e2cf6..7a0f4dc 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -37,48 +37,38 @@ static const QMap baudrateMap = { QPluginLoader Update::pluginLoader; -hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) { +hwinf *Update::loadDCPlugin(QString const &libCA /* absolute file path */) { 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; - } + QFileInfo libCAInfo(libCA); + if (libCAInfo.exists()) { + pluginLoader.setFileName(libCA); + // static QPluginLoader pluginLoader(pluginLibName); + if (!pluginLoader.load()) { + qCritical() << "cannot load plugin" << pluginLoader.fileName(); + qCritical() << pluginLoader.errorString(); + return nullptr; + } - qCritical() << "loadDCPlugin() plugin directory:" << plugInDir.absolutePath(); - qCritical() << "loadDCPlugin() plugin file name:" << pluginLoader.fileName(); + // 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(plugin))) { - qCritical() << "cannot cast plugin" << plugin << "to hwinf"; - return nullptr; - } - } else { - qCritical() << pluginLibName << "does not exist"; + if (!pluginLoader.isLoaded()) { + qCritical() << pluginLoader.errorString(); + return nullptr; + } + QObject *plugin = pluginLoader.instance(); + if (!plugin) { + qCritical() << "cannot start instance"; + return nullptr; + } + if (! (hw = qobject_cast(plugin))) { + qCritical() << "cannot cast plugin" << plugin << "to hwinf"; return nullptr; } } else { - qCritical() << "plugins directory" << plugInDir.absolutePath() - << "does not exist"; + qCritical() << libCAInfo.absoluteFilePath() << "does not exist"; return nullptr; } + return hw; } @@ -109,75 +99,18 @@ QString Update::dcVersion(QString const &dcBinFile) { } class hwapi; -Update::Update(QString customerRepository, - QString customerNrStr, - QString branchName, - QString plugInDir, - QString pluginName, - QString workingDir, - QString psaDcDir, - bool dryRun, - QObject *parent, - char const *serialInterface, - char const *baudrate) - : QObject(parent) { -#if 0 - - , 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_psaDcDir(psaDcDir) - , m_dryRun(dryRun) - , m_sys_areDCdataValid(false) { - - if (!m_hw) { - qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_hw == nullptr -> ca-slave plugin loaded ???"; - } else { - - // carun stoppen - } -#endif - m_start = QDateTime::currentDateTime(); +Update::Update(QString const &dcFileName, QString const &libCA, bool debug, bool noaction) + : m_dcFileName(dcFileName) + , m_hw(loadDCPlugin(libCA)) + , m_sys_areDCdataValid(false) + , m_debug(debug) + , m_noaction(noaction) { } Update::~Update() { unloadDCPlugin(); } -bool Update::openSerialPort() { - // const SettingsDialog::Settings p = m_settings->settings(); - m_serial->setPortName(SERIAL_PORT); - m_serial->setBaudRate(QSerialPort::Baud115200); - m_serial->setDataBits(QSerialPort::DataBits::Data8); - m_serial->setParity(QSerialPort::Parity::NoParity); - m_serial->setStopBits(QSerialPort::StopBits::OneStop); - m_serial->setFlowControl(QSerialPort::FlowControl::NoFlowControl); - if (m_serial->open(QIODevice::ReadWrite)) { - //showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6") - // .arg(p.name, p.stringBaudRate, p.stringDataBits, - // p.stringParity, p.stringStopBits, p.stringFlowControl)); - return true; - } else { - //QMessageBox::critical(this, tr("Error"), m_serial->errorString()); - //showStatusMessage(tr("Open error")); - } - return false; -} - -bool Update::closeSerialPort() { - if (m_serial->isOpen()) { - m_serial->close(); - return true; - } - return false; - //showStatusMessage(tr("Disconnected")); -} - Update::DownloadResult Update::sendStatus(int ret) const { switch (ret) { // return values of dc are: case 0: // 0: no answer by now @@ -280,8 +213,9 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { } bool Update::startBootloader() const { + qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader"; QThread::msleep(1000); - qInfo() << nextTimePoint().toUtf8().constData() << "starting bootloader ...done"; + qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader ...done"; return true; #if 0 @@ -304,6 +238,7 @@ bool Update::startBootloader() const { } bool Update::stopBootloader() const { + qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader"; QThread::msleep(1000); qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader ...done"; return true; @@ -325,6 +260,7 @@ bool Update::stopBootloader() const { } bool Update::resetDeviceController() const { + qInfo() << nextTimePoint().toUtf8().constData() << "resetting device controller"; // TODO // m_hw->bl_rebootDC(); @@ -439,19 +375,22 @@ QByteArray Update::loadBinaryDCFile(QString const &filename) const { // There is no problem to repeat this command until the // bootloader is really not running anymore. */ -bool Update::doUpdate(QString const &dcFileName) { - qInfo() << "" << Update::dcVersion(dcFileName); +int Update::run() { + if (!m_hw) { + qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_hw == nullptr -> ca-slave plugin loaded ???"; + return -(int)Result::PLUGIN_LOAD_ERROR; + } - m_dcFileName = dcFileName; + m_start = QDateTime::currentDateTime(); - //QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed()) - //: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed()); + if (m_debug) { + qInfo() << "start dc-update for" << m_dcFileName << "at" << m_start.toString(Qt::ISODate); + qInfo() << "" << Update::dcVersion(m_dcFileName); + } - //if (!m_hw) { - // qCritical() << "(" << __func__ << ":" << __LINE__ << "):" - // << "ERROR!!! m_hw == nullptr"; - // return false; - //} + m_hw->dc_autoRequest(false); + + qInfo() << "DC auto request OFF"; QByteArray ba = loadBinaryDCFile(m_dcFileName); if (ba.size() > 0) { @@ -462,6 +401,7 @@ bool Update::doUpdate(QString const &dcFileName) { // fill last block of data to be sent with 0xFF ba = ba.leftJustified(m_totalBlocks*64, (char)(0xFF)); + // TODO resetDeviceController(); if (startBootloader()) { int currentBlock = 0; @@ -499,10 +439,11 @@ bool Update::doUpdate(QString const &dcFileName) { qCritical() << "DownloadThread::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK()); #endif } + // TODO stopBootloader(); // there is no harm in stopping the bootloader even // if starting the bootloader failed qInfo() << nextTimePoint().toUtf8().constData() << ""; - return true; + return -(int)Result::SUCCESS; } qInfo() << nextTimePoint().toUtf8().constData() << ""; diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index edf0c62..f98f2ff 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -17,27 +17,21 @@ #ifdef PTU5 #define SERIAL_PORT "ttymxc2" +#define BAUDRATE 115200 #else #define SERIAL_PORT "ttyUSB0" +#define BAUDRATE 115200 #endif class QSerialPort; class Update : public QObject { Q_OBJECT + QString m_dcFileName{}; 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; - QString m_psaDcDir; - QString m_dcFileName; - bool m_maintenanceMode; - bool m_dryRun; - bool m_sys_areDCdataValid; + bool m_sys_areDCdataValid{}; + bool m_debug; + bool m_noaction; static QPluginLoader pluginLoader; @@ -47,34 +41,18 @@ class Update : public QObject { return QStringLiteral("+%1s").arg(secs, 7, 'f', 2, QChar('0')); } - bool openSerialPort(); - bool closeSerialPort(); - - QSerialPort *m_serial; - public: enum class DownloadResult {OK, ERROR, TIMEOUT, NOP}; - enum class FileTypeJson {CONFIG=1, DEVICE=2, CASH=3, SERIAL=4, TIME=5, PRINTER=6}; + enum class Result {SUCCESS=0, PLUGIN_LOAD_ERROR}; - static hwinf *loadDCPlugin(QDir const &plugInDir, QString const &fn); + static hwinf *loadDCPlugin(QString const &libCA = "/usr/lib/libCAslave.so"); static bool unloadDCPlugin(); static QStringList split(QString line, QChar sep = ','); - explicit Update(QString customerRepository, - QString customerNrStr, - QString branchName, - QString plugInDir, - QString pluginName, - QString workingDir, - QString psaDcDir, - bool dryRun = false, - QObject *parent = nullptr, - char const *serialInterface = SERIAL_PORT, - char const *baudrate = "115200"); - + explicit Update(QString const &dcBinFile, QString const &libCA, bool debug, bool noaction); virtual ~Update() override; - bool doUpdate(QString const &dcFileName); + int run(); static QString dcVersion(QString const &dcBinFile); private: From bef618a778009e456433ea97dd8e3c20f4965b83 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Mon, 7 Jul 2025 13:00:34 +0200 Subject: [PATCH 19/39] testing... --- DownloadDCFirmware/main.cpp | 3 +- DownloadDCFirmware/update.cpp | 4 + common/src/utils_internal.cpp | 166 ++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 common/src/utils_internal.cpp diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index b9e957f..0c1267a 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -65,7 +65,6 @@ int main(int argc, char **argv) { setDebugLevel(LOG_NOTICE); } - //return 0; /* @@ -172,7 +171,7 @@ int main(int argc, char **argv) { qInfo() << "using customer repository" << psaRepoDir; } - std::unique_ptr c = internal::dcCandidateToInstall(); + std::unique_ptr c = internal::dcCandidateToInstall("/etc/dc/"); if (c) { fi.setFile(*c); if (fi.exists() == false) { diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 7a0f4dc..52ac204 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -392,6 +392,10 @@ int Update::run() { qInfo() << "DC auto request OFF"; + // dennis einzelne linie + qCritical() << "start dc-update for" << m_dcFileName << "at" << m_start.toString(Qt::ISODate); + + QByteArray ba = loadBinaryDCFile(m_dcFileName); if (ba.size() > 0) { m_totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1; diff --git a/common/src/utils_internal.cpp b/common/src/utils_internal.cpp new file mode 100644 index 0000000..2615c87 --- /dev/null +++ b/common/src/utils_internal.cpp @@ -0,0 +1,166 @@ +#include "utils_internal.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace internal { + +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; +} + +QString customerRepoRoot() { + return "/opt/app/tools/atbupdate/"; +} + +QString customerRepoDirName() { + int const customerNr = read1stLineOfFile("/mnt/system_data/cust_nr"); + return (customerNr != -1) ? QString("customer_%1").arg(customerNr) : ""; +} + +QString customerRepoDir() { + QString const &n = customerRepoDirName(); + QString const &r = customerRepoRoot(); + return !n.isEmpty() ? QDir::cleanPath(r + QDir::separator() + n) : ""; +} + +QString customerRepoDcDir() { + QString const &r = customerRepoDir(); + return QDir::cleanPath(r + QDir::separator() + "etc/dc/"); +} + +bool customerRepoExists() { + QString const repoDir{customerRepoDir()}; + return !repoDir.isEmpty() ? QDir(repoDir).exists() : false; +} + +QString repositoryUrl() { + return "gitea@ptu-config.atb-comm.de:ATB/"; +} + +QString branchName() { + int const zoneNr = read1stLineOfFile("/mnt/system_data/zone_nr"); + if (zoneNr != -1) { + return QString("zg1/zone%1").arg(zoneNr); + } + return ""; +} + +std::unique_ptr readSettings(QString const &optionalDirName) { + std::unique_ptr settings{std::make_unique()}; + + QString const fileName{settings->applicationName() + ".ini"}; + QDir d; + + if (!optionalDirName.isEmpty()) { + d = QDir{optionalDirName}; + if (d.exists()) { // try to find ini-file under optionalDirname + QFileInfo fi{d, optionalDirName}; + if (fi.exists()) { + settings.reset(new QSettings(fi.absoluteFilePath(), QSettings::IniFormat)); + return settings; + } else { + qCritical() << fi.absoluteFilePath() << "not found." + << "Try" << internal::DEFAULT_INI_DIR; + } + } else { + qCritical() << optionalDirName << "not found." + << "Try" << internal::DEFAULT_INSTALL_DIR; + } + } + d = internal::DEFAULT_INI_DIR; + if (d.exists()) { // try to find ini-file under /etc/tools/atbupdate + QFileInfo fi{d, fileName}; + if (fi.exists()) { + settings.reset(new QSettings(fi.absoluteFilePath(), QSettings::IniFormat)); + return settings; + } else { + qCritical() << fi.absoluteFilePath() << "not found." + << "Try" << internal::DEFAULT_INSTALL_DIR; + } + } else { + qCritical() << internal::DEFAULT_INI_DIR << "not found." + << "Try" << internal::DEFAULT_INSTALL_DIR; + } + d = QDir{internal::DEFAULT_INSTALL_DIR}; + if (d.exists()) { // try to find ini-file under /opt/app/tools/atbupdate + QFileInfo fi{d, fileName}; + if (fi.exists()) { + settings.reset(new QSettings(fi.absoluteFilePath(), QSettings::IniFormat)); + return settings; + } else { + qCritical() << fi.absoluteFilePath() << "not found."; + } + } else { + qCritical() << internal::DEFAULT_INSTALL_DIR << "not found."; + } + + return settings; +} + +std::unique_ptr dcCandidateToInstall(QString const &dcDirectory) { + std::unique_ptr dcCandidate{nullptr}; + + qCritical() << __func__ << __LINE__ << dcDirectory; + + QDir dcDir{dcDirectory.isEmpty() ? customerRepoDcDir() : dcDirectory}; + if (dcDir.exists()) { + + QFileInfoList fileInfoList = + dcDir.entryInfoList(QStringList("*.bin"), + QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); + + QFileInfo dc2cbin{dcDir.absoluteFilePath("dc2c.bin")}; + + + if (dc2cbin.exists()) { + + QCryptographicHash md5gen(QCryptographicHash::Md5); + QByteArray ba_dc2cbin{}; + { + QFile f{dc2cbin.absoluteFilePath()}; + if (f.open(QIODevice::ReadOnly)) { + md5gen.addData(f.readAll()); + ba_dc2cbin = md5gen.result(); + md5gen.reset(); + } + } + + if (ba_dc2cbin.size() > 0) { + QFileInfoList::const_iterator it; + for (it = fileInfoList.cbegin(); it != fileInfoList.cend(); ++it) { + if (it->absoluteFilePath() != dc2cbin.absoluteFilePath()) { + QFile f{it->absoluteFilePath()}; + if (f.open(QIODevice::ReadOnly)) { + md5gen.addData(f.readAll()); + if (ba_dc2cbin == md5gen.result()) { + dcCandidate.reset(new QString(f.fileName())); + break; + } + md5gen.reset(); + } + } + } + } + } + } + + return dcCandidate; +} + +} // namespace internal From 4d91d1e5bbecb14f10e6dadb9f7f4098acaa42bc Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 12 Aug 2025 11:59:07 +0200 Subject: [PATCH 20/39] turn dc-download on --- DownloadDCFirmware/main.cpp | 2 +- DownloadDCFirmware/update.cpp | 43 +++++++++++++---------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 0c1267a..ad64256 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -189,7 +189,7 @@ int main(int argc, char **argv) { } Update u(fi.absoluteFilePath(), libca, debug, noaction); - u.run(); + // u.run(); qInfo() << ""; diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 52ac204..166c785 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -130,16 +130,11 @@ Update::sendNextAddress(int bNum) const { if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) { // qDebug() << "addr-block" << bNum << "..."; while (noAnswerCount <= 250) { - // TODO - // m_hw->bl_sendAddress(bNum); + m_hw->bl_sendAddress(bNum); QThread::msleep(100); - // TODO - // DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); - - DownloadResult const res = DownloadResult::OK; - + DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -179,20 +174,14 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { qInfo() << s.toUtf8().constData(); QThread::msleep(200); - return DownloadResult::OK; - // QByteArray b((const char *)(&local[0]), 64); - // qCritical() << "SNDB" << bNum << b.size() << b.toHex(); + QByteArray b((const char *)(&local[0]), 64); + qCritical() << "SNDB" << bNum << b.size() << b.toHex(); while (noAnswerCount <= 250) { - // TODO - // m_hw->bl_sendDataBlock(64, local); - - // TODO - // DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); - - DownloadResult const res = DownloadResult::OK; + m_hw->bl_sendDataBlock(64, local); + DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -213,12 +202,13 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { } bool Update::startBootloader() const { +#if 0 qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader"; QThread::msleep(1000); qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader ...done"; return true; +#else -#if 0 int nTry = 5; while (--nTry >= 0) { m_hw->bl_startBL(); @@ -234,16 +224,19 @@ bool Update::startBootloader() const { } qCritical() << "starting bootloader...FAILED"; return false; + #endif } bool Update::stopBootloader() const { +#if 0 qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader"; QThread::msleep(1000); qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader ...done"; return true; -#if 0 +#else + qDebug() << "stopping bootloader..."; int nTry = 5; while (--nTry >= 0) { @@ -256,13 +249,13 @@ bool Update::stopBootloader() const { } qCritical() << "stopping bootloader...FAILED"; return false; + #endif } bool Update::resetDeviceController() const { qInfo() << nextTimePoint().toUtf8().constData() << "resetting device controller"; - // TODO - // m_hw->bl_rebootDC(); + m_hw->bl_rebootDC(); // wait maximally 3 seconds, before starting bootloader QThread::sleep(1); @@ -280,12 +273,12 @@ QByteArray Update::loadBinaryDCFile(QString const &filename) const { if (!file.exists()) { qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << file.fileName() << "does not exist"; - return QByteArray(); + return QByteArray{}; } if (!file.open(QIODevice::ReadOnly)) { qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << "cannot open file" << file.fileName(); - return QByteArray(); + return QByteArray{}; } qInfo() << nextTimePoint().toUtf8().constData() @@ -392,10 +385,8 @@ int Update::run() { qInfo() << "DC auto request OFF"; - // dennis einzelne linie qCritical() << "start dc-update for" << m_dcFileName << "at" << m_start.toString(Qt::ISODate); - QByteArray ba = loadBinaryDCFile(m_dcFileName); if (ba.size() > 0) { m_totalBlocks = (((ba.size())%64)==0) ? (ba.size()/64) : (ba.size()/64)+1; @@ -415,8 +406,6 @@ int Update::run() { while (res != DownloadResult::ERROR && currentBlock < m_totalBlocks) { if ((res = sendNextAddress(currentBlock)) != DownloadResult::ERROR) { if ((res = sendNextDataBlock(ba, currentBlock)) != DownloadResult::ERROR) { - // TODO - // m_hw->dcDownloadSetCurrentBlockNumber(currentBlock); currentBlock += 1; } else break; } From ff5d0a891cf08ee24db1033795ec1b1ab5d81518 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 13 Aug 2025 11:16:15 +0200 Subject: [PATCH 21/39] startBootloader(): set wait time to 1000ms. set try counter to 10. a message to ask for general bl installation (in hardware) --- DownloadDCFirmware/update.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 166c785..b57bbfe 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -209,10 +209,10 @@ bool Update::startBootloader() const { return true; #else - int nTry = 5; + int nTry = 10; while (--nTry >= 0) { m_hw->bl_startBL(); - QThread::msleep(5000); + QThread::msleep(1000); m_hw->bl_checkBL(); if (m_hw->bl_isUp()) { qInfo() << "starting bootloader...OK"; @@ -220,6 +220,7 @@ bool Update::startBootloader() const { return true; } else { qCritical() << "bootloader not up (" << nTry << ")"; + qCritical() << "IS BOOTLOADER INSTALLED ???"; } } qCritical() << "starting bootloader...FAILED"; @@ -241,7 +242,7 @@ bool Update::stopBootloader() const { int nTry = 5; while (--nTry >= 0) { m_hw->bl_stopBL(); - QThread::msleep(500); + QThread::msleep(1000); if (!m_hw->bl_isUp()) { qInfo() << "stopping bootloader...OK"; return true; @@ -399,6 +400,7 @@ int Update::run() { // TODO resetDeviceController(); if (startBootloader()) { +#if 0 int currentBlock = 0; DownloadResult res = DownloadResult::OK; qInfo() << nextTimePoint().toUtf8().constData() << "64-byte block" << currentBlock; @@ -410,7 +412,7 @@ int Update::run() { } else break; } } - +#endif #if 0 qCritical() << "DownloadThread::run(): last 64-byte block %04d" << currentBlock; From fc41883e6aa4652f0b6e4ec959fe2f7ab553fcef Mon Sep 17 00:00:00 2001 From: Oswaldo Palma Date: Mon, 18 Aug 2025 08:55:24 +0200 Subject: [PATCH 22/39] "increased BL_start Timer (500 -> 1000) " --- DownloadDCFirmware/main.cpp | 2 +- DownloadDCFirmware/update.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index ad64256..0c1267a 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -189,7 +189,7 @@ int main(int argc, char **argv) { } Update u(fi.absoluteFilePath(), libca, debug, noaction); - // u.run(); + u.run(); qInfo() << ""; diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index b57bbfe..8118617 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -400,19 +400,19 @@ int Update::run() { // TODO resetDeviceController(); if (startBootloader()) { -#if 0 + int currentBlock = 0; DownloadResult res = DownloadResult::OK; qInfo() << nextTimePoint().toUtf8().constData() << "64-byte block" << currentBlock; - while (res != DownloadResult::ERROR && currentBlock < m_totalBlocks) { + while (res != DownloadResult::ERROR && currentBlock <= m_totalBlocks) { if ((res = sendNextAddress(currentBlock)) != DownloadResult::ERROR) { if ((res = sendNextDataBlock(ba, currentBlock)) != DownloadResult::ERROR) { currentBlock += 1; } else break; } } -#endif + #if 0 qCritical() << "DownloadThread::run(): last 64-byte block %04d" << currentBlock; From 379ca35db2b423bd353a65c48f4232fa86b98fbf Mon Sep 17 00:00:00 2001 From: Oswaldo Palma Date: Mon, 18 Aug 2025 13:04:50 +0200 Subject: [PATCH 23/39] "shortened time to sendnextblock." --- DownloadDCFirmware/update.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 8118617..473203c 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -132,8 +132,8 @@ Update::sendNextAddress(int bNum) const { while (noAnswerCount <= 250) { m_hw->bl_sendAddress(bNum); - QThread::msleep(100); - + QThread::msleep(10); //from 100ms to 20ms +//################################################################################### DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { @@ -173,7 +173,8 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { qInfo() << s.toUtf8().constData(); - QThread::msleep(200); + QThread::msleep(20); //reduce from 200 to 50 ms + //############################################################################ QByteArray b((const char *)(&local[0]), 64); qCritical() << "SNDB" << bNum << b.size() << b.toHex(); From 47ac11fb9ab1bf11b5d1482a31eefcb08b634f8a Mon Sep 17 00:00:00 2001 From: Oswaldo Palma Date: Mon, 18 Aug 2025 13:06:25 +0200 Subject: [PATCH 24/39] "after dc_download restart autorequest or else E255" --- DownloadDCFirmware/update.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 473203c..094eeae 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -439,9 +439,11 @@ int Update::run() { stopBootloader(); // there is no harm in stopping the bootloader even // if starting the bootloader failed qInfo() << nextTimePoint().toUtf8().constData() << ""; + m_hw->dc_autoRequest(true); //restart dc_autoRequest after download else E255! return -(int)Result::SUCCESS; } qInfo() << nextTimePoint().toUtf8().constData() << ""; + //To Do Error handling if Dc doesnt start after download return false; } From de9304f867b227ee0595d8a608c83a4235ef8619 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 19 Aug 2025 10:14:12 +0200 Subject: [PATCH 25/39] Add define for TEST_DC_DOWNLOAD and add corresponding code to test the download without actual dc-controller on the PTU. --- DownloadDCFirmware/update.cpp | 56 ++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 094eeae..584a6bb 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -30,6 +30,10 @@ #define UPDATE_OPKG (1) #define UPDATE_DC (0) + +// TODO: dynamisch setzen +#define TEST_DC_DOWNLOAD (0) // 0/1 + static const QMap baudrateMap = { {"1200" , 0}, {"9600" , 1}, {"19200" , 2}, {"38400" , 3}, {"57600" , 4}, {"115200" , 5} @@ -130,11 +134,16 @@ Update::sendNextAddress(int bNum) const { if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) { // qDebug() << "addr-block" << bNum << "..."; while (noAnswerCount <= 250) { + +#if TEST_DC_DOWNLOAD==0 m_hw->bl_sendAddress(bNum); QThread::msleep(10); //from 100ms to 20ms //################################################################################### DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); +#else + DownloadResult const res = DownloadResult::OK; +#endif if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -180,9 +189,15 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { qCritical() << "SNDB" << bNum << b.size() << b.toHex(); while (noAnswerCount <= 250) { + +#if TEST_DC_DOWNLOAD==0 m_hw->bl_sendDataBlock(64, local); DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); +#else + DownloadResult const res = DownloadResult::OK; +#endif + if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -203,13 +218,9 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { } bool Update::startBootloader() const { -#if 0 - qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader"; - QThread::msleep(1000); - qInfo() << nextTimePoint().toUtf8().constData() << "start boot loader ...done"; - return true; -#else + qDebug() << "starting bootloader..."; +#if TEST_DC_DOWNLOAD==0 int nTry = 10; while (--nTry >= 0) { m_hw->bl_startBL(); @@ -225,21 +236,18 @@ bool Update::startBootloader() const { } } qCritical() << "starting bootloader...FAILED"; - return false; - +#else + QThread::msleep(1000); + qInfo() << "starting bootloader...OK"; + return true; #endif + return false; } bool Update::stopBootloader() const { -#if 0 - qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader"; - QThread::msleep(1000); - qInfo() << nextTimePoint().toUtf8().constData() << "stopping bootloader ...done"; - return true; - -#else - qDebug() << "stopping bootloader..."; + +#if TEST_DC_DOWNLOAD==0 int nTry = 5; while (--nTry >= 0) { m_hw->bl_stopBL(); @@ -250,14 +258,22 @@ bool Update::stopBootloader() const { } } qCritical() << "stopping bootloader...FAILED"; - return false; +#else // Test code + QThread::msleep(1000); + qInfo() << "stopping bootloader...OK"; + return true; #endif + + return false; } bool Update::resetDeviceController() const { qInfo() << nextTimePoint().toUtf8().constData() << "resetting device controller"; + +#if TEST_DC_DOWNLOAD==0 m_hw->bl_rebootDC(); +#endif // wait maximally 3 seconds, before starting bootloader QThread::sleep(1); @@ -383,7 +399,9 @@ int Update::run() { qInfo() << "" << Update::dcVersion(m_dcFileName); } +#if TEST_DC_DOWNLOAD==0 m_hw->dc_autoRequest(false); +#endif qInfo() << "DC auto request OFF"; @@ -398,7 +416,6 @@ int Update::run() { // fill last block of data to be sent with 0xFF ba = ba.leftJustified(m_totalBlocks*64, (char)(0xFF)); - // TODO resetDeviceController(); if (startBootloader()) { @@ -439,7 +456,10 @@ int Update::run() { stopBootloader(); // there is no harm in stopping the bootloader even // if starting the bootloader failed qInfo() << nextTimePoint().toUtf8().constData() << ""; + +#if TEST_DC_DOWNLOAD==0 m_hw->dc_autoRequest(true); //restart dc_autoRequest after download else E255! +#endif return -(int)Result::SUCCESS; } From 0c6b219d31f3c494067bad5f170b1bc48af171c1 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 20 Aug 2025 11:11:02 +0200 Subject: [PATCH 26/39] read ATBUpdateDCsettings in *.ini file --- DownloadDCFirmware/main.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 0c1267a..84d8755 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -145,14 +145,11 @@ int main(int argc, char **argv) { QString libca; std::unique_ptr settings = internal::readSettings(); - if (settings) { - settings->beginGroup("COMMON"); - debug = settings->value("debug", false).toBool(); - settings->endGroup(); - settings->beginGroup("RUNTIME"); - noaction = settings->value("noaction", true).toBool(); - workingDir = settings->value("workingdir", "/tmp").toBool(); + if (settings) { + settings->beginGroup("ATBUpdateDC"); + debug = settings->value("debug", false).toBool(); + workingDir = settings->value("workingdir", "/tmp").toString(); libca = settings->value("libca", "/usr/lib/libCAslave.so").toString(); settings->endGroup(); } From 9c403218570baea543d7e5f2ebfc696f37e79976 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 20 Aug 2025 11:12:56 +0200 Subject: [PATCH 27/39] Minor: init. m_debug to false. --- DownloadDCFirmware/update.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadDCFirmware/update.h b/DownloadDCFirmware/update.h index f98f2ff..cc8cbc6 100644 --- a/DownloadDCFirmware/update.h +++ b/DownloadDCFirmware/update.h @@ -30,7 +30,7 @@ class Update : public QObject { QString m_dcFileName{}; hwinf *m_hw = nullptr; bool m_sys_areDCdataValid{}; - bool m_debug; + bool m_debug{false}; bool m_noaction; static QPluginLoader pluginLoader; From ea1abc68da1b82ca89939700daef4ffaba817463 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 20 Aug 2025 11:15:09 +0200 Subject: [PATCH 28/39] Replace TEST_DC_DOWNLOAD with m_debug. --- DownloadDCFirmware/update.cpp | 106 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 584a6bb..79777ee 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -26,14 +26,12 @@ #include #include #include +#include #define UPDATE_OPKG (1) #define UPDATE_DC (0) -// TODO: dynamisch setzen -#define TEST_DC_DOWNLOAD (0) // 0/1 - static const QMap baudrateMap = { {"1200" , 0}, {"9600" , 1}, {"19200" , 2}, {"38400" , 3}, {"57600" , 4}, {"115200" , 5} @@ -135,15 +133,15 @@ Update::sendNextAddress(int bNum) const { // qDebug() << "addr-block" << bNum << "..."; while (noAnswerCount <= 250) { -#if TEST_DC_DOWNLOAD==0 - m_hw->bl_sendAddress(bNum); + DownloadResult res = DownloadResult::OK; + if (!m_debug) { + m_hw->bl_sendAddress(bNum); - QThread::msleep(10); //from 100ms to 20ms + QThread::msleep(10); //from 100ms to 20ms //################################################################################### - DownloadResult const res = sendStatus(m_hw->bl_wasSendingAddOK()); -#else - DownloadResult const res = DownloadResult::OK; -#endif + res = sendStatus(m_hw->bl_wasSendingAddOK()); + } + if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { @@ -157,7 +155,7 @@ Update::sendNextAddress(int bNum) const { } else { noAnswerCount += 1; // no answer by now } - } + } // while // wait max. about 3 seconds return DownloadResult::TIMEOUT; } @@ -190,13 +188,12 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { while (noAnswerCount <= 250) { -#if TEST_DC_DOWNLOAD==0 - m_hw->bl_sendDataBlock(64, local); + DownloadResult res = DownloadResult::OK; - DownloadResult const res = sendStatus(m_hw->bl_wasSendingDataOK()); -#else - DownloadResult const res = DownloadResult::OK; -#endif + if (!m_debug) { + m_hw->bl_sendDataBlock(64, local); + res = sendStatus(m_hw->bl_wasSendingDataOK()); + } if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { @@ -220,60 +217,61 @@ Update::sendNextDataBlock(QByteArray const &binary, int bNum) const { bool Update::startBootloader() const { qDebug() << "starting bootloader..."; -#if TEST_DC_DOWNLOAD==0 - int nTry = 10; - while (--nTry >= 0) { - m_hw->bl_startBL(); - QThread::msleep(1000); - m_hw->bl_checkBL(); - if (m_hw->bl_isUp()) { - qInfo() << "starting bootloader...OK"; - QThread::msleep(5000); - return true; - } else { - qCritical() << "bootloader not up (" << nTry << ")"; - qCritical() << "IS BOOTLOADER INSTALLED ???"; + if (!m_debug) { + int nTry = 10; + while (--nTry >= 0) { + m_hw->bl_startBL(); + QThread::msleep(1000); + m_hw->bl_checkBL(); + if (m_hw->bl_isUp()) { + qInfo() << "starting bootloader...OK"; + QThread::msleep(5000); + return true; + } else { + qCritical() << "bootloader not up (" << nTry << ")"; + qCritical() << "IS BOOTLOADER INSTALLED ???"; + } } + qCritical() << "starting bootloader...FAILED"; + return false; + } else { + QThread::msleep(1000); + qInfo() << "starting bootloader...OK"; } - qCritical() << "starting bootloader...FAILED"; -#else - QThread::msleep(1000); - qInfo() << "starting bootloader...OK"; + return true; -#endif - return false; } bool Update::stopBootloader() const { qDebug() << "stopping bootloader..."; -#if TEST_DC_DOWNLOAD==0 - int nTry = 5; - while (--nTry >= 0) { - m_hw->bl_stopBL(); - QThread::msleep(1000); - if (!m_hw->bl_isUp()) { - qInfo() << "stopping bootloader...OK"; - return true; + if (!m_debug) { + int nTry = 5; + while (--nTry >= 0) { + m_hw->bl_stopBL(); + QThread::msleep(1000); + if (!m_hw->bl_isUp()) { + qInfo() << "stopping bootloader...OK"; + return true; + } } + qCritical() << "stopping bootloader...FAILED"; + return false; + + } else { + QThread::msleep(1000); + qInfo() << "stopping bootloader...OK"; } - qCritical() << "stopping bootloader...FAILED"; -#else // Test code - QThread::msleep(1000); - qInfo() << "stopping bootloader...OK"; return true; -#endif - - return false; } bool Update::resetDeviceController() const { qInfo() << nextTimePoint().toUtf8().constData() << "resetting device controller"; -#if TEST_DC_DOWNLOAD==0 - m_hw->bl_rebootDC(); -#endif + if (!m_debug) { + m_hw->bl_rebootDC(); + } // wait maximally 3 seconds, before starting bootloader QThread::sleep(1); From a30f8334f1d70db1b7f22620d621c4c4c6d5bde8 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Thu, 21 Aug 2025 10:51:16 +0200 Subject: [PATCH 29/39] Replace TEST_DC_DOWNLOAD with m_debug. --- DownloadDCFirmware/update.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 79777ee..71e73c7 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -397,9 +397,9 @@ int Update::run() { qInfo() << "" << Update::dcVersion(m_dcFileName); } -#if TEST_DC_DOWNLOAD==0 - m_hw->dc_autoRequest(false); -#endif + if (!m_debug) { + m_hw->dc_autoRequest(false); + } qInfo() << "DC auto request OFF"; @@ -455,9 +455,10 @@ int Update::run() { // if starting the bootloader failed qInfo() << nextTimePoint().toUtf8().constData() << ""; -#if TEST_DC_DOWNLOAD==0 - m_hw->dc_autoRequest(true); //restart dc_autoRequest after download else E255! -#endif + if (!m_debug) { + m_hw->dc_autoRequest(true); //restart dc_autoRequest after download else E255! + } + return -(int)Result::SUCCESS; } From f2af48eee329dd8d243027a2198c640705258f0d Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Mon, 25 Aug 2025 13:55:49 +0200 Subject: [PATCH 30/39] after dc-download, check if device-controller reboots successfully --- DownloadDCFirmware/update.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index 71e73c7..a082925 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -450,16 +450,25 @@ int Update::run() { qCritical() << "DownloadThread::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK()); #endif } - // TODO stopBootloader(); // there is no harm in stopping the bootloader even // if starting the bootloader failed - qInfo() << nextTimePoint().toUtf8().constData() << ""; + // check if update was successful if (!m_debug) { m_hw->dc_autoRequest(true); //restart dc_autoRequest after download else E255! } - return -(int)Result::SUCCESS; + for (int i = 0; i < 3; ++i) { + qInfo() << "waiting for device controller restart...(" << i << ")"; + QThread::sleep(20); + + resetDeviceController(); + if (startBootloader()) { + qInfo() << nextTimePoint().toUtf8().constData() << ""; + stopBootloader(); + return -(int)Result::SUCCESS; + } + } } qInfo() << nextTimePoint().toUtf8().constData() << ""; From 553782a2ead366885da54c4b1bc6bfa0f9bf7be1 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 13:22:05 +0100 Subject: [PATCH 31/39] Add common/include/utils_internal.h --- common/include/utils_internal.h | 92 +++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 common/include/utils_internal.h diff --git a/common/include/utils_internal.h b/common/include/utils_internal.h new file mode 100644 index 0000000..c8b0cca --- /dev/null +++ b/common/include/utils_internal.h @@ -0,0 +1,92 @@ +#ifndef UTILS_INTERNAL_H_INCLUDED +#define UTILS_INTERNAL_H_INCLUDED + +#include +#include +#include + +namespace internal { + + static constexpr const char *UPDATE_NOT_NECESSARY{"not necessary"}; + static constexpr const char *UPDATE_NOT_REQUESTED{"not requested"}; + static constexpr const char *UPDATE_INITIAL{"initial update"}; + static constexpr const char *UPDATE_REQUESTED{"requested"}; + + static constexpr const char *NO_CUSTOMER_REPOSITORY{"no customer repository"}; + static constexpr const int NO_CUSTOMER_REPOSITORY_CODE{-8}; + static constexpr const char *NO_ETC_CUSTOMER_REPOSITORY{"no etc/ in customer repository"}; + static constexpr const int NO_ETC_CUSTOMER_REPOSITORY_CODE{-9}; + static constexpr const char *NO_OPT_CUSTOMER_REPOSITORY{"no opt/ in customer repository"}; + static constexpr const int NO_OPT_CUSTOMER_REPOSITORY_CODE{-10}; + + static constexpr const char *ISMAS_CONNECTED{"connected"}; + static constexpr const char *ISMAS_DISCONNECTED{"disconnected"}; + static constexpr const char *ISMAS_DISCONNECTING{"disconnecting"}; + static constexpr const char *ISMAS_NOT_CONNECTED{"not connected"}; + static constexpr const char *ISMAS_CONNECTION_IN_PROGRESS{"connecting"}; + + static constexpr const char *BROKER_CONNECTED{"connected"}; + static constexpr const char *BROKER_DISCONNECTED{"disconnected"}; + static constexpr const char *BROKER_DISCONNECTING{"disconnecting"}; + static constexpr const char *BROKER_NOT_CONNECTED{"not connected"}; + static constexpr const char *BROKER_CONNECTION_IN_PROGRESS{"connecting"}; + + static constexpr const int GIT_CHECKOUT_ERROR_CODE{-2}; + static constexpr const int GIT_PULL_ERROR_CODE{-4}; + static constexpr const int GIT_NOT_NECESSARY_CODE{1}; + static constexpr const int GIT_UPDATED_CODE{2}; + static constexpr const int GIT_CLONED_CODE{3}; + + static constexpr const char *GIT_CUSTOMER_REPO_CHECKOUT_ERROR{"checkout error"}; + static constexpr const char *GIT_CUSTOMER_REPO_PULL_ERROR{"pull error"}; + static constexpr const char *GIT_CUSTOMER_REPO_UP_TO_DATE{"up to date"}; + static constexpr const char *GIT_CUSTOMER_REPO_NO_UPDATE_NECESSARY{"no repository update necessary"}; + static constexpr const char *GIT_CUSTOMER_REPO_NOT_NECESSARY{"not necessary"}; + static constexpr const char *GIT_CUSTOMER_REPO_UPDATED{"repository updated"}; + static constexpr const char *GIT_CUSTOMER_REPO_CLONED{"repository cloned"}; + static constexpr const char *GIT_UPDATED{"updated"}; + + static constexpr const char *EXEC_OPKG_COMMANDS_SUCCESS{"success"}; + static constexpr const char *EXEC_OPKG_COMMANDS_FAIL{"FAIL"}; + static constexpr const char *EXEC_OPKG_COMMANDS_NOACTION_SUCCESS{"success"}; + static constexpr const char *EXEC_OPKG_COMMANDS_NOACTION_FAIL{"FAIL"}; + + + static constexpr const char *UPDATE_DC_JSON_FILES_SUCCESS{"success"}; + + static constexpr const char *SYNC_CUSTOMER_REPO_FILES_SUCCESS{"success"}; + + static constexpr const char *UPDATE_DC_FIRMARE_SUCCESS{"success"}; + + static constexpr const char *OPKG_MARKER{""}; + static constexpr const char *SYNC_MARKER{""}; + static constexpr const char *DC_MARKER{""}; + static constexpr const char *GIT_MARKER{""}; + static constexpr const char *ISMAS_MARKER{""}; + + static constexpr const int PERCENT_CHECK_ISMAS_CONNECIVITY{10}; + static constexpr const int PERCENT_CHECK_UPDATE_REQUEST{20}; + static constexpr const int PERCENT_CHECK_CUSTOMER_REPOSITORY{30}; + static constexpr const int PERCENT_INSTALL_SW_PACKETS_NOACTION{40}; + static constexpr const int PERCENT_INSTALL_SW_PACKETS{50}; + static constexpr const int PERCENT_INSTALL_DC_CONFIGURATION{60}; + static constexpr const int PERCENT_SYNCHRONIZE_REPO_AND_FILESYS{70}; + static constexpr const int PERCENT_UPDATE_DC{80}; + static constexpr const int PERCENT_SHOW_FINAL_STATUS{90}; + + static constexpr const char *DEFAULT_INI_DIR{"/etc/tools/atbupdate/"}; + static constexpr const char *DEFAULT_INSTALL_DIR{"/opt/app/tools/atbupdate/"}; + + int read1stLineOfFile(QString fileName); + QString customerRepoRoot(); + QString customerRepoDir(); + QString customerRepoDcDir(); + QString customerRepoDirName(); + QString repositoryUrl(); + QString branchName(); + bool customerRepoExists(); + std::unique_ptr readSettings(QString const &optionalDirName = ""); + std::unique_ptr dcCandidateToInstall(QString const &dcDirectory, QString const &rootDir = ""); + } + + #endif // UTILS_INTERNAL_H_INCLUDED From 47e7e1e796dc19afd1165695a8578aadaf659f15 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 13:59:13 +0100 Subject: [PATCH 32/39] Add common/command --- common/include/command.h | 49 +++++++++++++++ common/src/command.cpp | 128 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 common/include/command.h create mode 100644 common/src/command.cpp diff --git a/common/include/command.h b/common/include/command.h new file mode 100644 index 0000000..33b155f --- /dev/null +++ b/common/include/command.h @@ -0,0 +1,49 @@ +#ifndef COMMAND_H_INCLUDED +#define COMMAND_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +class Command : public QObject { + Q_OBJECT + + QString m_command; + QString m_commandResult; + + int m_waitForStartTimeout; + int m_waitForFinishTimeout; + bool m_verbose; + int m_exitCode; + QString m_workingDirectory; + + QScopedPointer m_p; + + QStringList m_args; + +public: + Command(QString command, + QStringList args, + QString workingDirectory, + bool verbose = true, + int start_timeout = 100000, + int finish_timeout = 100000); + + void resetCommandResult() { m_commandResult.clear(); } + QString getCommandResult(bool reset = false); + QString const &command() const { return m_command; } + QString const &commandResult() const { return m_commandResult; } + QStringList const &args() const { return m_args; } + + bool exec(); + int exitCode() const { return m_exitCode; } + +private slots: + virtual void readyReadStandardOutput(); + virtual void readyReadStandardError(); +}; + +#endif // COMMAND_H_INCLUDED diff --git a/common/src/command.cpp b/common/src/command.cpp new file mode 100644 index 0000000..28b8c19 --- /dev/null +++ b/common/src/command.cpp @@ -0,0 +1,128 @@ +#include "command.h" + +#include +#include +#include +#include +#include + +Command::Command(QString command, QStringList args, QString workingDirectory, + bool verbose, int start_timeout, int finish_timeout) + : m_command(command.trimmed()) + , m_commandResult("") + , m_waitForStartTimeout(start_timeout) + , m_waitForFinishTimeout(finish_timeout) + , m_verbose(verbose) + , m_exitCode(-1) + , m_workingDirectory(workingDirectory) + , m_args(args) { + m_p.reset(new QProcess(this)); + if (m_p) { + m_p->setWorkingDirectory(workingDirectory); + m_p->setProcessChannelMode(QProcess::MergedChannels); + + connect(m_p.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput())); + connect(m_p.get(), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError())); + } +} + +void Command::readyReadStandardOutput() { + QProcess *p = (QProcess *)sender(); + if (p) { + QString s = p->readAllStandardOutput(); + if (m_verbose) { +// qCritical().noquote() << s; + m_commandResult += s; + } + } +} + +void Command::readyReadStandardError() { + QProcess *p = (QProcess *)sender(); + if (p) { + QString s = p->readAllStandardError(); +// qCritical().noquote() << s; + m_commandResult += s; + } +} + + +QString Command::getCommandResult(bool reset) { + if (reset == false) { + return m_commandResult; + } + + QString commandResult = m_commandResult; + m_commandResult.clear(); + + return commandResult; +} + +bool Command::exec() { + + if (!m_args.isEmpty()) { + m_p->start(m_command, m_args); + } else { + m_p->start(m_command); + } + + qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + bool started = false; + if ((started = m_p->waitForStarted(m_waitForStartTimeout)) == true) { + // qCritical() << "PROCESS" << m_command << "STARTED IN" << m_p->workingDirectory(); + if (m_p->state() == QProcess::ProcessState::Running) { + // 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) || + m_command.trimmed().startsWith("opkg", Qt::CaseInsensitive)) { + wait = -1; + } + bool const no_timeout = m_p->waitForFinished(wait); + if (no_timeout) { + // qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory(); + if (m_p->exitStatus() == QProcess::NormalExit) { + if ((m_exitCode = m_p->exitCode()) == 0) { + qCritical().noquote() << m_p->readAllStandardOutput(); + //qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); + //qDebug() << "EXECUTED" << m_command + // << QString("(runtime %1ms)").arg(end-start) + // << "with code" << m_exitCode + // << "IN" << m_p->workingDirectory(); + return true; + } else { + qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); + qCritical() << "EXECUTED" << m_command + << QString("(runtime %1ms)").arg(end-start) + << "with code" << m_exitCode + << "IN" << m_p->workingDirectory(); + } + } else { + qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); + qCritical() << "PROCESS" << m_command << "CRASHED with code" + << m_p->exitCode() + << QString("(after %1ms)").arg(end-start) + << "IN" << m_p->workingDirectory(); + } + } else { + qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); + qCritical() << "PROCESS" << m_command + << "DID NOT FINISH WITH" << wait + << "MS IN" << m_p->workingDirectory() + << QString("(runtime %1ms)").arg(end-start); + } + } else { + qCritical() << "WRONG PROCESS STATE" << m_p->state() + << "IN" << m_p->workingDirectory(); + } + } else { + qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); + qCritical() << "PROCESS" << m_command << "TIMEOUT AT START" + << QString("(runtime %1ms)").arg(end-start) + << "IN" << m_p->workingDirectory() << m_waitForStartTimeout; + } + + return false; +} + From 2ac87e93e477a0fdfd3a7f7cbb3736196342a50f Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 13:59:41 +0100 Subject: [PATCH 33/39] UpdateDC: use common/command --- DownloadDCFirmware/update.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadDCFirmware/update.cpp b/DownloadDCFirmware/update.cpp index a082925..7627e31 100644 --- a/DownloadDCFirmware/update.cpp +++ b/DownloadDCFirmware/update.cpp @@ -1,5 +1,5 @@ #include "update.h" -#include "process/command.h" +#include "command.h" #include #include From e7f78fe97615d2f47e51ae2a244b8b5bc06e591e Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 15:10:18 +0100 Subject: [PATCH 34/39] Fix: merge-conflict from 'save for christmas' ... 518bd870336d61b9b32424d668750c3923cc9387 2024-12-20 13:01:34 --- UpdatePTUDevCtrl/mainwindow.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/UpdatePTUDevCtrl/mainwindow.cpp b/UpdatePTUDevCtrl/mainwindow.cpp index 7fe8487..c17b24d 100644 --- a/UpdatePTUDevCtrl/mainwindow.cpp +++ b/UpdatePTUDevCtrl/mainwindow.cpp @@ -27,6 +27,7 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) , m_updateStep(UpdateDcEvent::UpdateStep::NONE) { ui->setupUi(this); + checkOrientation(); this->setStatusBar(new QStatusBar(this)); QFont f; @@ -36,12 +37,6 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent) f.setPointSize(11); this->statusBar()->setFont(f); -<<<<<<< HEAD - ui->setupUi(this); - checkOrientation(); - -======= ->>>>>>> 7bfb7f5... save for christmas ui->updateProgress->setRange(0, 100); ui->updateProgress->reset(); From 7b0e17c478a4f837072bb2f7e74e19a564dcd4ce Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 15:14:09 +0100 Subject: [PATCH 35/39] common/utils_internal: use state from df4e384d9d80 --- common/include/utils_internal.h | 2 +- common/src/utils_internal.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/include/utils_internal.h b/common/include/utils_internal.h index c8b0cca..4cdb23a 100644 --- a/common/include/utils_internal.h +++ b/common/include/utils_internal.h @@ -86,7 +86,7 @@ namespace internal { QString branchName(); bool customerRepoExists(); std::unique_ptr readSettings(QString const &optionalDirName = ""); - std::unique_ptr dcCandidateToInstall(QString const &dcDirectory, QString const &rootDir = ""); + std::unique_ptr dcCandidateToInstall(QString const &dcDirectory); } #endif // UTILS_INTERNAL_H_INCLUDED diff --git a/common/src/utils_internal.cpp b/common/src/utils_internal.cpp index 2615c87..365c6ee 100644 --- a/common/src/utils_internal.cpp +++ b/common/src/utils_internal.cpp @@ -64,7 +64,8 @@ QString branchName() { std::unique_ptr readSettings(QString const &optionalDirName) { std::unique_ptr settings{std::make_unique()}; - QString const fileName{settings->applicationName() + ".ini"}; + //QString const fileName{settings->applicationName() + ".ini"}; + QString const fileName{"ATBUpdateTool.ini"}; QDir d; if (!optionalDirName.isEmpty()) { From 057e4603cec1ead6ca3fa457db30cd849c3ecaf1 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Thu, 5 Feb 2026 16:19:33 +0100 Subject: [PATCH 36/39] ATBUpdateDC: use ATBUpdateTool.ini --- DownloadDCFirmware/main.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/DownloadDCFirmware/main.cpp b/DownloadDCFirmware/main.cpp index 84d8755..793db15 100644 --- a/DownloadDCFirmware/main.cpp +++ b/DownloadDCFirmware/main.cpp @@ -142,15 +142,23 @@ int main(int argc, char **argv) { bool debug = false; bool noaction = true; QString workingDir; + QString libDir; QString libca; std::unique_ptr settings = internal::readSettings(); if (settings) { - settings->beginGroup("ATBUpdateDC"); - debug = settings->value("debug", false).toBool(); + settings->beginGroup("DIRECTORIES"); workingDir = settings->value("workingdir", "/tmp").toString(); - libca = settings->value("libca", "/usr/lib/libCAslave.so").toString(); + libDir = settings->value("plugin-directory", "/usr/lib/").toString(); + settings->endGroup(); + + settings->beginGroup("FLAGS"); + debug = settings->value("debug", false).toBool(); + settings->endGroup(); + + settings->beginGroup("PLUGINS"); + libca = libDir + settings->value("plugin-name", "libCAslave.so").toString(); settings->endGroup(); } From de1bf61e7c3776155a029a00e3f7fdc582f5adf2 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Tue, 10 Feb 2026 14:25:17 +0100 Subject: [PATCH 37/39] git-client: add note about GIT_SSH_COMMAND env variants --- UpdatePTUDevCtrl/git/git_client.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UpdatePTUDevCtrl/git/git_client.cpp b/UpdatePTUDevCtrl/git/git_client.cpp index 4f433d6..0eac2aa 100644 --- a/UpdatePTUDevCtrl/git/git_client.cpp +++ b/UpdatePTUDevCtrl/git/git_client.cpp @@ -400,6 +400,12 @@ std::optional GitClient::gitPull() { If remote host keys are changed, then export GIT_SSH_COMMAND="ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig" + + ... or ignore host key checking: + export GIT_SSH_COMMAND="ssh -i /opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig -o StrictHostKeyChecking=no" + + ... or use separate known_hosts file: + export GIT_SSH_COMMAND="ssh -i /mypath/.keys/id_ed25519 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/opt/app/tools/atbupdate/.keys/known_hosts git pull leads to the following warning/error message: From 12d65bf372a18ff948ab192c0c310dcc0d467173 Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Tue, 10 Feb 2026 14:26:19 +0100 Subject: [PATCH 38/39] commandline_parser: add options ... for sshKeyFile and StrictHostKeyChecking. Set correct default values. --- UpdatePTUDevCtrl/commandline_parser.cpp | 62 ++++++++++++++++++++----- UpdatePTUDevCtrl/commandline_parser.h | 6 +++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/UpdatePTUDevCtrl/commandline_parser.cpp b/UpdatePTUDevCtrl/commandline_parser.cpp index 67613d7..b379b28 100644 --- a/UpdatePTUDevCtrl/commandline_parser.cpp +++ b/UpdatePTUDevCtrl/commandline_parser.cpp @@ -6,7 +6,9 @@ #include CommandLineParser::CommandLineParser() - : m_repositoryUrl("https://git.mimbach49.de/GerhardHoffmann") + : m_repositoryUrl("gitea@ptu-config.atb-comm.de:ATB/") + , m_sshKeyFile("/opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig") + , m_sshOptionStrictHostKeyChecking("false") , m_plugInDir("/usr/lib/") , m_plugInName("libCAslave.so") , m_workingDir("/opt/app/tools/atbupdate/") @@ -20,27 +22,36 @@ CommandLineParser::CommandLineParser() , m_alwaysDownloadDC("false") , m_repositoryUrlOption( QCommandLineOption( - QStringList() << "repository-url" << "repository-url", + QStringList() << "repository-url", QCoreApplication::translate("main", "Where to find a customer repository."), QCoreApplication::translate("main", "directory"))) + , m_sshKeyFileOption( + QCommandLineOption( + QStringList() << "sshKeyFile", + QCoreApplication::translate("main", "Used ssh key."), + QCoreApplication::translate("main", "file"))) + , m_sshOptionStrictHostKeyCheckingOption( + QCommandLineOption( + QStringList() << "sshStrictHostKeyChecking", + QCoreApplication::translate("main", "Enable ssh strict host key checking"))) , m_iniFileDirectoryOption( QCommandLineOption( - QStringList() << "ini-directory" << "ini-directory", + QStringList() << "ini-directory", QCoreApplication::translate("main", "Where to find an ini-file."), QCoreApplication::translate("main", "directory"))) , m_iniFileNameOption( QCommandLineOption( - QStringList() << "ini-filename" << "ini-filename", + QStringList() << "ini-filename", QCoreApplication::translate("main", "Name of ini-file."), QCoreApplication::translate("main", "file"))) , m_pluginDirectoryOption( QCommandLineOption( - QStringList() << "plugin-directory" << "plugin-directory", + QStringList() << "plugin-directory", QCoreApplication::translate("main", "Where to find dc-plugin."), QCoreApplication::translate("main", "directory"))) , m_pluginNameOption( QCommandLineOption( - QStringList() << "plugin-name" << "plugin-name", + QStringList() << "plugin-name", QCoreApplication::translate("main", "Name of dc-plugin."), QCoreApplication::translate("main", "directory"))) , m_noDownloadOption( @@ -57,17 +68,17 @@ CommandLineParser::CommandLineParser() QCoreApplication::translate("main", "Always download the dc-bin-file to DC)."))) , m_workingDirectoryOption( QCommandLineOption( - QStringList() << "working-directory" << "working-directory", + QStringList() << "working-directory", QCoreApplication::translate("main", "working directory of update-script."), QCoreApplication::translate("main", "directory"))) , m_psaConfigDirectoryOption( QCommandLineOption( - QStringList() << "psa-config-directory" << "psa-config-directory", + QStringList() << "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", + QStringList() << "psa-tariff-directory", QCoreApplication::translate("main", "tariff directory of tariff-json-files."), QCoreApplication::translate("main", "directory"))) , m_dryRunOption( @@ -94,8 +105,8 @@ CommandLineParser::CommandLineParser() , m_readDCVersionOption( QCommandLineOption( QStringList() << "D" << "read-dc-version", - QCoreApplication::translate("main", "Show version of device controller."), - QCoreApplication::translate("main", "Show version of device controller."))) { + QCoreApplication::translate("main", "Show version of device controller."))) +{ configure(); } @@ -104,9 +115,15 @@ void CommandLineParser::configure() { m_parser.addHelpOption(); m_parser.addVersionOption(); - m_repositoryUrlOption.setDefaultValue("https://git.mimbach49.de/GerhardHoffmann"); + m_repositoryUrlOption.setDefaultValue("gitea@ptu-config.atb-comm.de:ATB/"); m_parser.addOption(m_repositoryUrlOption); + m_sshKeyFileOption.setDefaultValue("/opt/app/tools/atbupdate/.keys/id_ed25519_ptuConfig"); + m_parser.addOption(m_sshKeyFileOption); + + m_sshOptionStrictHostKeyCheckingOption.setDefaultValue(""); + m_parser.addOption(m_sshOptionStrictHostKeyCheckingOption); + m_iniFileDirectoryOption.setDefaultValue(QCoreApplication::applicationDirPath()); m_parser.addOption(m_iniFileDirectoryOption); @@ -177,6 +194,12 @@ void CommandLineParser::readSettings() { if (key.contains("repository-url")) { m_repositoryUrl = v.toString(); } else + if (key.contains("sshKeyFile")) { + m_sshKeyFile = v.toString(); + } else + if (key.contains("sshOptionStrictHostKeyChecking")) { + m_sshOptionStrictHostKeyChecking = (v.toBool() ? "true" : "false"); + } else if (key.contains("plugin-directory")) { m_plugInDir = v.toString(); } else @@ -237,6 +260,21 @@ QString CommandLineParser::repositoryUrl() { return m_repositoryUrl; } +QString CommandLineParser::sshKeyFile() { + if (m_parser.isSet(m_sshKeyFileOption)) { + m_sshKeyFile = m_parser.value(m_sshKeyFileOption); + } + return m_sshKeyFile; +} + +bool CommandLineParser::sshOptionStrictHostKeyChecking() +{ + if (m_parser.isSet(m_sshOptionStrictHostKeyCheckingOption)) { + m_sshOptionStrictHostKeyChecking = m_parser.value(m_sshOptionStrictHostKeyCheckingOption); + } + return m_sshOptionStrictHostKeyChecking == "false" ? false : true; +} + QString CommandLineParser::plugInDir() { if (m_parser.isSet(m_pluginDirectoryOption)) { m_plugInDir = m_parser.value(m_pluginDirectoryOption); diff --git a/UpdatePTUDevCtrl/commandline_parser.h b/UpdatePTUDevCtrl/commandline_parser.h index 082680d..9e577c1 100644 --- a/UpdatePTUDevCtrl/commandline_parser.h +++ b/UpdatePTUDevCtrl/commandline_parser.h @@ -8,6 +8,8 @@ class CommandLineParser : public QCommandLineParser { QString m_repositoryUrl; + QString m_sshKeyFile; + QString m_sshOptionStrictHostKeyChecking; QString m_plugInDir; QString m_plugInName; QString m_workingDir; @@ -25,6 +27,8 @@ class CommandLineParser : public QCommandLineParser { QString m_dcDir{"etc/dc/"}; QCommandLineOption m_repositoryUrlOption; + QCommandLineOption m_sshKeyFileOption; + QCommandLineOption m_sshOptionStrictHostKeyCheckingOption; QCommandLineOption m_iniFileDirectoryOption; QCommandLineOption m_iniFileNameOption; QCommandLineOption m_pluginDirectoryOption; @@ -57,6 +61,8 @@ public: QString const &iniFileName() const { return m_iniFileName; } void readSettings(); QString repositoryUrl(); + QString sshKeyFile(); + bool sshOptionStrictHostKeyChecking(); QString plugInDir(); QString plugInName(); QString workingDir(); From f7b334429276d406bc278ec7b932a35a72ccfbcb Mon Sep 17 00:00:00 2001 From: Siegfried Siegert Date: Tue, 10 Feb 2026 14:28:13 +0100 Subject: [PATCH 39/39] main: use configuration for setting variables ... -> remove wrong default values. -> remove dependency for certain host-names --- UpdatePTUDevCtrl/main.cpp | 45 +++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/UpdatePTUDevCtrl/main.cpp b/UpdatePTUDevCtrl/main.cpp index c8f4770..524f82c 100644 --- a/UpdatePTUDevCtrl/main.cpp +++ b/UpdatePTUDevCtrl/main.cpp @@ -72,39 +72,43 @@ int main(int argc, char *argv[]) { CommandLineParser parser; parser.process(a); + + if (parser.isSet(parser.addHelpOption())) { + parser.showHelp(0); + return 0; + } + parser.readSettings(); QString repositoryUrl = parser.repositoryUrl(); + QString sshKeyFile = parser.sshKeyFile(); + bool strictHostKeyChecking = parser.sshOptionStrictHostKeyChecking(); if (repositoryUrl.endsWith('/')) { repositoryUrl.chop(1); } - QString gitSSHCommand(""); + // default for gitSSHCommand + QString gitSSHCommand = "ssh -i " + sshKeyFile; - 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..."; + strictHostKeyChecking ? gitSSHCommand.append(" -o StrictHostKeyChecking=yes") + : gitSSHCommand.append(" -o StrictHostKeyChecking=no"); + + QByteArray const v = qgetenv("GIT_SSH_COMMAND"); + if (v.isEmpty()) { + if (QFileInfo(sshKeyFile).exists()) { + if (!qputenv("GIT_SSH_COMMAND", QByteArray(gitSSHCommand.toStdString().c_str()))) { + qCritical() << "ERROR: GIT_SSH_COMMAND not put into env. 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; - } + 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; } QString plugInDir = parser.plugInDir(); @@ -161,7 +165,6 @@ int main(int argc, char *argv[]) { return 0; } - QThread::currentThread()->setObjectName("main thread"); qInfo() << "Main thread" << QThread::currentThreadId();