Compare commits

..

No commits in common. "dc-download-firmware" and "master" have entirely different histories.

21 changed files with 357 additions and 978 deletions

View File

@ -52,7 +52,7 @@ int main(int argc, char **argv) {
}
// qputenv("XDG_RUNTIME_DIR", "/var/run/user/0");
openlog("DC", LOG_PERROR | LOG_CONS, LOG_USER);
openlog("ATB-UPDATE-DC-FIRMWARE", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
QApplication a(argc, argv);
QApplication::setApplicationName("ATBDownloadDCFirmware");
@ -73,7 +73,6 @@ int main(int argc, char **argv) {
QString workingDir = parser.workingDir();
QString psaConfigDir = parser.psaConfigDir();
QString psaTariffDir = parser.psaTariffDir();
QString psaDcDir = parser.dcDir();
QString iniFileName = parser.iniFileName();
bool const dryRun = parser.dryRun();
bool const noUpdatePsaHardware = parser.noUpdatePsaHardware();
@ -82,7 +81,6 @@ 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();
@ -111,73 +109,27 @@ int main(int argc, char **argv) {
qInfo() << "machineNr ................" << machineNr;
qInfo() << "customerNr ..............." << customerNr;
qInfo() << "zoneNr ..................." << zoneNr;
qInfo() << "readDCVersion ............" << readDCVersion;
qInfo() << "dcDir ...................." << psaDcDir;
if (!QDir(plugInDir).exists()) {
qCritical() << plugInDir
<< "does not exists, but has to contain dc-library";
exit(-1);
}
if (showExtendedVersion) {
printf(APP_EXTENDED_VERSION"\n");
return 0;
}
QString const &customerRepo
= QDir::cleanPath(workingDir + QDir::separator() + QString("customer_%1").arg(customerNr));
// etc/dc: located under mount-path
std::optional<QString> 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());
}
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();
qInfo() << "Main thread" << QThread::currentThreadId();
Update update(customerRepo,
QString::number(customerNr),
branchName,
plugInDir,
plugInName,
workingDir,
psaDcDir);
MainWindow mw;
update.doUpdate(fi.absoluteFilePath());
// MainWindow mw;
// mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
// mw.showFullScreen();
// qCritical() << "SHOW";
// mw.show();
qInfo() << "<DC-UPDATE-FINISH>";
return 0;
// return a.exec();
}

View File

@ -1,5 +1,4 @@
#include "update.h"
#include "process/command.h"
#include <QCoreApplication>
#include <QFile>
@ -22,8 +21,6 @@
#include <QDateTime>
#include <QPluginLoader>
#include <QMap>
#include <QStringList>
#include <QString>
#define UPDATE_OPKG (1)
#define UPDATE_DC (0)
@ -95,17 +92,6 @@ bool Update::unloadDCPlugin() {
return false;
}
QString Update::dcVersion(QString const &dcBinFile) {
QProcess p;
QStringList params;
params << "-c" << QString(R"(strings %1 | grep DC2c.\[0-9\] | uniq)").arg(dcBinFile);
p.start("bash", params);
p.waitForFinished();
return QString(p.readAllStandardOutput()).trimmed().split(QRegularExpression("\\s")).first();
}
class hwapi;
Update::Update(QString customerRepository,
QString customerNrStr,
@ -113,14 +99,11 @@ Update::Update(QString customerRepository,
QString plugInDir,
QString pluginName,
QString workingDir,
QString psaDcDir,
bool dryRun,
QObject *parent,
char const *serialInterface,
char const *baudrate)
: QObject(parent) {
#if 0
: QObject(parent)
, m_hw(loadDCPlugin(QDir(plugInDir), pluginName))
, m_serialInterface(serialInterface)
, m_baudrate(baudrate)
@ -129,356 +112,100 @@ Update::Update(QString customerRepository,
, 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 {
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);
}
// carun stoppen
qCritical() << "(" << __func__ << ":" << __LINE__ << ") m_sys_areDCDataValid ..."
<< m_sys_areDCdataValid;
}
#endif
m_start = QDateTime::currentDateTime();
}
Update::~Update() {
unloadDCPlugin();
}
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:;
bool Update::doUpdate(QStringList const &filesToWorkOn, bool usbStickDetected) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
return false;
}
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) {
// TODO
// m_hw->bl_sendAddress(bNum);
QThread::msleep(100);
// 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) {
qCritical() << "addr-block" << bNum << "...FAILED";
return res;
}
} else { // res == DownloadResult::OK
qInfo() << nextTimePoint().toUtf8().constData() << "addr-block" << bNum << "...done";
return res;
}
} else {
noAnswerCount += 1; // no answer by now
}
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;
}
// 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;
QString s = nextTimePoint();
s += " sending block ";
s += QString("%1/%2 ...done <PROGRESS>").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) {
// 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) {
qCritical() << "data for block" << bNum << "...FAILED";
return res;
}
} else {
qInfo() << nextTimePoint().toUtf8().constData() << "data for block"
<< QString("%1/%2").arg(bNum).arg(m_totalBlocks) << "done";
return res;
}
} else {
noAnswerCount += 1; // no answer by now
}
}
// wait max. about 3 seconds
return DownloadResult::TIMEOUT;
}
bool Update::startBootloader() const {
QThread::msleep(1000);
qInfo() << nextTimePoint().toUtf8().constData() << "starting bootloader ...done";
return true;
#if 0
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;
#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) {
m_hw->bl_stopBL();
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! DC DATA NOT VALID -> CA-SLAVE-PLUGIN NOT CONNECTED (" << tries << ")";
m_hw->dc_autoRequest(true);
QThread::msleep(500);
if (!m_hw->bl_isUp()) {
qInfo() << "stopping bootloader...OK";
return true;
}
}
qCritical() << "stopping bootloader...FAILED";
return false;
#endif
}
bool Update::resetDeviceController() const {
// TODO
// m_hw->bl_rebootDC();
// wait maximally 3 seconds, before starting bootloader
QThread::sleep(1);
qInfo() << nextTimePoint().toUtf8().constData()
<< "resetting device controller ...done";
return true;
}
QByteArray Update::loadBinaryDCFile(QString const &filename) const {
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();
}
qInfo() << nextTimePoint().toUtf8().constData()
<< "loading dc binary to memory" << Update::dcVersion(filename) << "...done";
bool res = false;
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 &dcFileName) {
qInfo() << "<DC-VERSION>" << 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;
//}
QByteArray ba = loadBinaryDCFile(m_dcFileName);
if (ba.size() > 0) {
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(m_totalBlocks*64, (char)(0xFF));
resetDeviceController();
if (startBootloader()) {
int currentBlock = 0;
DownloadResult res = DownloadResult::OK;
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) {
// TODO
// m_hw->dcDownloadSetCurrentBlockNumber(currentBlock);
currentBlock += 1;
} else break;
QList<QString>::const_iterator it;
for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
QString const &fToWorkOn = usbStickDetected ? QDir::cleanPath(it->trimmed())
: QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed());
if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
res = true;
int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
if ((templateIdx < 1) || (templateIdx > 32)) {
qCritical() << "WRONG TEMPLATE INDEX" << templateIdx;
res = false;
} else {
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
qCritical() <<
QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
.arg(fToWorkOn)
.arg(templateIdx);
}
}
#if 0
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_cash", Qt::CaseInsensitive)
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
if ((res = updateCashConf(fToWorkOn))) {
qCritical() << QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn);
}
qCritical() << "DownloadThread::run(): last result" << (int)sendStatus(m_hw->bl_wasSendingDataOK());
#endif
} 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;
}
stopBootloader(); // there is no harm in stopping the bootloader even
// if starting the bootloader failed
qInfo() << nextTimePoint().toUtf8().constData() << "<DC-UPDATE-SUCCESS>";
return true;
}
qInfo() << nextTimePoint().toUtf8().constData() << "<DC-UPDATE-FAILURE>";
return false;
return res;
}
#if 0
bool Update::checkJsonVersions(QStringList const& jsonFileNames) {
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
@ -709,4 +436,3 @@ bool Update::updateCashConf(QString jsFile) {
bool Update::updateDeviceConf(QString jsFile) {
return downloadJson(FileTypeJson::DEVICE, 0, jsFile);
}
#endif

View File

@ -8,8 +8,6 @@
#include <QByteArray>
#include <QProcess>
#include <QPluginLoader>
#include <QDateTime>
#include <cmath>
#include <initializer_list>
@ -32,20 +30,12 @@ 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};
@ -54,13 +44,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,
@ -68,22 +58,72 @@ public:
virtual ~Update() override;
bool doUpdate(QString const &dcFileName);
static QString dcVersion(QString const &dcBinFile);
bool doUpdate(QStringList const &jsonFilesToDownload, bool usbStickDetected = false);
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 updatePrinterTemplate(int templateIdx, QString fname) const;
bool updateConfig(QString jsFileToSendToDC);
bool updateCashConf(QString jsFileToSendToDC);
bool updateDeviceConf(QString jsFileToSendToDC);
QString m_fileToDownload;
uint16_t m_totalBlocks = 0;
bool downloadJson(enum FileTypeJson type, int templateIdx,
QString jsFileToSendToDC) const;
QString getFileVersion(QString const& jsonFileName);
bool checkJsonVersions(QStringList const& jsonFileNames =
QStringList(
QList(
std::initializer_list<QString>{
QString("etc/psa_config/DC2C_conf.json"),
QString("etc/psa_config/DC2C_cash.json"),
QString("etc/psa_config/DC2C_device.json"),
QString("etc/psa_config/DC2C_print01.json"),
QString("etc/psa_config/DC2C_print02.json"),
QString("etc/psa_config/DC2C_print03.json"),
QString("etc/psa_config/DC2C_print04.json"),
QString("etc/psa_config/DC2C_print05.json"),
QString("etc/psa_config/DC2C_print06.json"),
QString("etc/psa_config/DC2C_print07.json"),
QString("etc/psa_config/DC2C_print08.json"),
QString("etc/psa_config/DC2C_print09.json"),
QString("etc/psa_config/DC2C_print10.json"),
QString("etc/psa_config/DC2C_print11.json"),
QString("etc/psa_config/DC2C_print12.json"),
QString("etc/psa_config/DC2C_print13.json"),
QString("etc/psa_config/DC2C_print14.json"),
QString("etc/psa_config/DC2C_print15.json"),
QString("etc/psa_config/DC2C_print16.json"),
QString("etc/psa_config/DC2C_print17.json"),
QString("etc/psa_config/DC2C_print18.json"),
QString("etc/psa_config/DC2C_print19.json"),
QString("etc/psa_config/DC2C_print20.json"),
QString("etc/psa_config/DC2C_print21.json"),
QString("etc/psa_config/DC2C_print22.json"),
QString("etc/psa_config/DC2C_print23.json"),
QString("etc/psa_config/DC2C_print24.json"),
QString("etc/psa_config/DC2C_print25.json"),
QString("etc/psa_config/DC2C_print26.json"),
QString("etc/psa_config/DC2C_print27.json"),
QString("etc/psa_config/DC2C_print28.json"),
QString("etc/psa_config/DC2C_print29.json"),
QString("etc/psa_config/DC2C_print30.json"),
QString("etc/psa_config/DC2C_print31.json"),
QString("etc/psa_config/DC2C_print32.json")})));
/*
bool checkDownloadedJsonVersions(QStringList const& jsonFileNames);
hwinf *hw() { return m_hw; }
hwinf const *hw() const { return m_hw; }
//QString customerId() { return m_customerId; }
//QString const customerId() const { return m_customerId; }
QString branchName() { return m_branchName; }
QString const branchName() const { return m_branchName; }
//QString repositoryPath() { return m_repositoryPath; }
//QString const repositoryPath() const { return m_repositoryPath; }
private:
static QString jsonType(enum FileTypeJson type);
bool openSerial(int br, QString baudrate, QString comPort) const;

View File

@ -85,17 +85,7 @@ CommandLineParser::CommandLineParser()
, m_yoctoInstallStatusOption(
QCommandLineOption(
QStringList() << "Y" << "yocto-install",
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."))) {
QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."))) {
configure();
}
@ -148,12 +138,6 @@ 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() {
@ -161,8 +145,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 +155,8 @@ void CommandLineParser::readSettings() {
for (QString const &key: keys) {
QVariant v = settings.value(key);
//qCritical() << "(" << __func__ << ":" << __LINE__ << ")"
// << key << " -> " << v.toString();
qCritical() << __PRETTY_FUNCTION__
<< key << " -> " << v.toString();
if (key.contains("repository-url")) {
m_repositoryUrl = v.toString();
@ -212,12 +196,6 @@ 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();
@ -265,20 +243,6 @@ 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() {
if (m_parser.isSet(m_readDCVersionOption)) {
m_readDCVersion = m_parser.value(m_readDCVersionOption);
}
return m_readDCVersion == "false" ? false : true;
}
QString CommandLineParser::workingDir() {
if (m_parser.isSet(m_workingDirectoryOption)) {
m_workingDir = m_parser.value(m_workingDirectoryOption);
@ -324,9 +288,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;
}

View File

@ -1,4 +1,4 @@
#ifndef COMMAND_LINE_PARSER_H_INCLUDED
#ifndef COMMAND_LINE_PARSER_H_INCLUDED
#define COMMAND_LINE_PARSER_H_INCLUDED
#include <QCoreApplication>
@ -11,8 +11,8 @@ class CommandLineParser : public QCommandLineParser {
QString m_plugInDir;
QString m_plugInName;
QString m_workingDir;
QString m_psaConfigDir{"etc/psa_config"};
QString m_psaTariffDir{"etc/psa_tariff"};
QString m_psaConfigDir;
QString m_psaTariffDir;
QString m_dryRun;
QString m_noUpdatePsaHardware;
QString m_showYoctoVersion;
@ -21,8 +21,6 @@ class CommandLineParser : public QCommandLineParser {
QString m_iniFileName;
QString m_alwaysDownloadConfig;
QString m_alwaysDownloadDC;
QString m_readDCVersion{"false"};
QString m_dcDir{"etc/dc/"};
QCommandLineOption m_repositoryUrlOption;
QCommandLineOption m_iniFileDirectoryOption;
@ -39,8 +37,6 @@ class CommandLineParser : public QCommandLineParser {
QCommandLineOption m_extendedVersionOption;
QCommandLineOption m_yoctoVersionOption;
QCommandLineOption m_yoctoInstallStatusOption;
QCommandLineOption m_dcDirectoryOption;
QCommandLineOption m_readDCVersionOption;
QCommandLineParser m_parser;
@ -69,7 +65,5 @@ public:
bool extendedVersion();
bool alwaysDownloadConfig();
bool alwaysDownloadDC();
bool readDCVersion();
QString dcDir();
};
#endif // COMMAND_LINE_PARSER_H_INCLUDED

View File

@ -2,7 +2,6 @@
#include "update.h"
#include "worker.h"
#include "utils.h"
#include "process/command.h"
#include <QRegularExpression>
#include <QDebug>

View File

@ -4,8 +4,8 @@
#include <QObject>
#include <QStringList>
#include <optional>
#include <QCoreApplication>
#include "process/command.h"
#include "ismas/ismas_client.h"
class Worker;

View File

@ -31,7 +31,6 @@
#include "worker.h"
#include "mainwindow.h"
#include "utils.h"
// #include "process/command.h"
#include <QThread>
#include <QtWidgets>
@ -200,9 +199,5 @@ int main(int argc, char *argv[]) {
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
mw.showFullScreen();
// test
worker.dcUpdate();
// worker.summary();
return a.exec();
}

View File

@ -11,8 +11,6 @@
#include <QDebug>
#include <QScrollBar>
#include <QEvent>
#include <QColor>
#include <QColorDialog>
MainWindow::MainWindow(Worker *worker, QWidget *parent)
@ -23,16 +21,16 @@ 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.setPointSize(11);
f.setPixelSize(12);
this->statusBar()->setFont(f);
ui->setupUi(this);
ui->updateProgress->setRange(0, 100);
ui->updateProgress->reset();
@ -40,15 +38,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->updateLabel->setText(lst.join('\n'));
ui->updateLabel->setEnabled(true);
ui->updateStatus->setText(lst.join('\n'));
ui->updateStatus->setEnabled(true);
// ui->updateStatus->installEventFilter(this);
m_startTimer = new QTimer(this);
@ -80,15 +78,11 @@ 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)));
@ -97,29 +91,6 @@ 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;
@ -228,12 +199,6 @@ 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));

View File

@ -36,11 +36,8 @@ 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);
@ -51,9 +48,6 @@ 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,6 +74,5 @@ private:
//int m_progressValue;
UpdateDcEvent::UpdateStep m_updateStep;
QTimer *m_statusTimer;
QString m_targetDcVersion;
};
#endif // MAINWINDOW_H

View File

@ -12,10 +12,7 @@
</property>
<property name="font">
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
<family>Source Code Pro</family>
</font>
</property>
<property name="windowTitle">
@ -32,28 +29,21 @@
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="stepLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="font">
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<item row="3" column="2">
<widget class="QPushButton" name="exit">
<property name="text">
<string/>
<string>Exit</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<item row="3" column="1">
<widget class="QProgressBar" name="updateProgress">
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="3" colspan="3">
<widget class="QTextEdit" name="updateStatus">
<property name="enabled">
<bool>true</bool>
@ -62,16 +52,9 @@
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
@ -81,44 +64,6 @@
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="3">
<widget class="QLabel" name="updateLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="font">
<font>
<family>Misc Fixed</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QProgressBar" name="updateProgress">
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="exit">
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
</layout>

View File

@ -1,86 +1,33 @@
#include "command.h"
#include "worker.h"
#include <QProcess>
#include <QDebug>
#include <QDir>
#include <QRegularExpression>
#include <QDateTime>
#include <QMutexLocker>
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_p(nullptr)
, m_worker(nullptr) {
, m_exitCode(-1) {
}
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;
QString Command::getCommandResult() const {
return m_commandResult;
}
void Command::readyReadStandardOutput() {
QMutexLocker locker(&m_mtx);
QProcess *p = (QProcess *)sender();
if (p) {
QString s = p->readAllStandardOutput();
if (m_worker) {
int i = -1;
if ((i = s.indexOf("<DC-VERSION>")) != -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("<PROGRESS>")) != -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("<DC-UPDATE-FINISH>")) != -1) {
m_worker->summary();
// qApp->exit(0);
} else
if ((i = s.indexOf("<DC-UPDATE-SUCCESS>")) != -1) {
m_worker->summary();
} else
if ((i = s.indexOf("<DC-UPDATE-FAILURE>")) != -1) {
m_worker->summary();
//qApp->exit(-1);
} else {
emit m_worker->insertText(s);
}
}
m_commandResult += s;
}
m_commandResult += p->readAllStandardOutput();
// qCritical() << m_commandResult;
}
void Command::readyReadStandardError() {
QProcess *p = (QProcess *)sender();
if (p) {
QByteArray buf = p->readAllStandardError();
qCritical() << buf;
}
QByteArray buf = p->readAllStandardError();
qCritical() << buf;
}
void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
@ -88,38 +35,12 @@ 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()));
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)) {

View File

@ -7,34 +7,27 @@
#include <QString>
#include <QStringList>
#include <QProcess>
#include <QMutex>
class Worker;
class Command : public QObject {
Q_OBJECT
QString m_command;
mutable QString m_commandResult;
QString m_commandResult;
int m_waitForStartTimeout;
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,
int finish_timeout = 100000);
QString getCommandResult(bool reset = false) const;
QString getCommandResult() const;
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();

View File

@ -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,54 @@ 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;
#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
}
}
Update::~Update() {
@ -132,6 +181,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;
}
/*
///////////////////////////////////////////////////////////////////////////////
@ -216,23 +302,98 @@ void Update::onReportDCDownloadFailure(QString const &errorMsg) {
// 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;
#if 0
QFile fn(fileToSendToDC);
if (!fn.exists()) {
// output via CONSOLE() etc
return false;
}
qInfo() << "updating dc-binary" << fileToSendToDC << "...";
bool bl_isUp = false;
if (m_hw->bl_completeStart()) {
int cnt = 5;
while (--cnt > 0) {
if (m_hw->bl_isUp()) {
bl_isUp = true;
break;
}
}
}
return false;
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 +512,6 @@ bool Update::downloadJson(enum FileTypeJson type,
// QThread::sleep(1); // make sure the auto-request flag is acknowledged
}
#endif
return true;
}
@ -410,7 +570,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 +592,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 +625,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 +703,6 @@ bool Update::checkDownloadedJsonVersions(QStringList const& jsonFileNames) {
}
}
#endif
return false;
}
@ -556,7 +710,6 @@ QMap<QString, QString>
Update::getInstalledJsonVersions(QStringList const& jsonFileNames) {
QMap<QString, QString> map;
#if 0
if (!m_hw) {
qCritical() << "(" << __func__ << ":" << __LINE__ << "):"
<< "ERROR!!! m_hw == nullptr";
@ -656,13 +809,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 +1020,4 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
qDebug() << "SET AUTO-REQUEST=TRUE";
return res;
#endif
return false;
}

View File

@ -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; }

View File

@ -13,65 +13,9 @@
#include <QDir>
#include <QDirIterator>
#include <QRegularExpression>
#include <QProcess>
#include <QJsonDocument>
#include <QJsonValue>
#include <QJsonObject>
#include <QJsonArray>
#include <fstream>
QVector<QPair<QString, QString>> Utils::installedPackages() {
QVector<QPair<QString, QString>> 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<QString, QString> 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()) {

View File

@ -9,7 +9,6 @@
#include <QDateTime>
#include <QDir>
#include <QDebug>
#include <QPair>
namespace Utils {
int read1stLineOfFile(QString fileName);
@ -34,8 +33,6 @@ namespace Utils {
QString getParentName();
bool isATBQTRunning();
QVector<QPair<QString, QString>> installedPackages();
}
#endif // UTILS_H_INCLUDED

View File

@ -26,7 +26,6 @@
#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]");
@ -177,14 +176,9 @@ 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;
@ -290,8 +284,6 @@ void Worker::privateUpdate() {
return;
}
return;
QString func(__PRETTY_FUNCTION__);
GUI() << (ISMAS() << (CONSOLE() << UPDATE_STEP::STARTED));
@ -1275,7 +1267,6 @@ 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();
@ -1297,7 +1288,6 @@ QStringList Worker::getDCVersion() const {
}
}
}
#endif
return lst;
}
@ -1510,78 +1500,3 @@ 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<QPair<QString, QString>> 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);
}

View File

@ -15,6 +15,7 @@
#include <optional>
#include <initializer_list>
#include "update.h"
#include "git/git_client.h"
#include "ismas/ismas_client.h"
#include "utils.h"
@ -134,8 +135,6 @@
#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{
@ -190,7 +189,6 @@ class Worker : public QThread{
QStringList m_ismasTriggerStatusMessage;
MainWindow *m_mainWindow;
Command *m_dcDownloadFirmware;
bool m_withoutIsmasDirectPort;
QString m_apismVersion;
@ -460,13 +458,8 @@ 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);
@ -477,9 +470,6 @@ signals:
void restartExitTimer();
void enableExit();
void disableExit();
void showDcDownload(QString);
void showSummary(QString);
void setDcDownloadProgress(int);
private slots:
bool updateTriggerSet();
@ -497,8 +487,6 @@ private:
bool computeFilesToDownload();
bool execOpkgCommands();
QDateTime m_start;
static const QMap<UPDATE_STEP, const char*> smap;
// CONSOLE()

View File

@ -25,9 +25,7 @@ public:
static bool umountSDCard();
static std::optional<QString> checkForUSBStick(QString const &dirPathUnderMountPath = ".");
static std::optional<QString> checkForSDCard(QString const &dirPathUnderMountPath = ".");
static QString getUSBMountPath(QString const &dirPathUnderMountPath = ".");
static QString getSDMountPath(QString const &dirPathUnderMountPath = ".");
//static QString getUSBDeviceName();
static bool umountUSBStick();
@ -56,8 +54,7 @@ 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

View File

@ -265,20 +265,6 @@ std::optional<QString> System::checkForUSBStick(QString const &dirPathUnderMount
return mountPath.isEmpty() ? std::nullopt : std::optional<QString>(mountPath);
}
std::optional<QString> 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<QString>(mountPath);
}
/**
@ -329,7 +315,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);
@ -346,64 +332,6 @@ 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;
@ -426,38 +354,6 @@ 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.
*