save for christmas

This commit is contained in:
2024-12-20 13:01:34 +01:00
parent 2ec7b61682
commit 7bfb7f5a3b
19 changed files with 624 additions and 92 deletions

View File

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

View File

@@ -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<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());
}
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() << "<DC-UPDATE-FINISH>";
return 0;
// return a.exec();
}

View File

@@ -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 <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) {
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() << "<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;
}
//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() << "<DC-UPDATE-SUCCESS>";
return true;
}
qInfo() << nextTimePoint().toUtf8().constData() << "<DC-UPDATE-FAILURE>";
return false;
}

View File

@@ -8,6 +8,8 @@
#include <QByteArray>
#include <QProcess>
#include <QPluginLoader>
#include <QDateTime>
#include <cmath>
#include <initializer_list>
@@ -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);