Compare commits

..

16 Commits
1.3.2 ... 1.3.5

Author SHA1 Message Date
1197598a3d Set version to 1.3.5 2023-09-21 16:52:42 +02:00
ec13e97226 Update interfaces.h to HWapi/4.6 2023-09-21 15:55:31 +02:00
a8dd9d7e24 Merge branch 'master' of git.mimbach49.de:GerhardHoffmann/UpdatePTUDevCtrl 2023-09-21 15:50:19 +02:00
82751eb1d4 Set version to 1.3.4. 2023-09-11 10:14:41 +02:00
17a4a69df2 Added some debug output for parent-process-name 2023-09-11 10:14:04 +02:00
a03261d04a Fixed getParentName() to work analogously to isATBQTRunning(). 2023-09-11 10:12:20 +02:00
7832ef5d8c Set version to 1.3.3. 2023-09-10 17:22:49 +02:00
9c213d0a97 Added some better debug output in the slots concerned with the text edit
of the main window ("update status").
Use insertPlainText() when adding to the text edit to simplify code.
2023-09-10 16:55:32 +02:00
18378afdc5 Did some testing with event filters on the main window. not used. 2023-09-10 16:54:54 +02:00
6dd8a8c6b3 did some testing with event filter. not used. 2023-09-10 16:54:29 +02:00
adfb358e12 Add some output to see if start of the update tool is configured correctly. 2023-09-10 16:51:36 +02:00
ff418b11a1 Use plauginLoader as a dedicated static object. 2023-09-10 16:51:07 +02:00
38e79f0354 Use pluginLoader as a dedicated static object. 2023-09-10 16:50:19 +02:00
103b3f3f9c isATBQTRunning():
Use std::fstream to read /proc/<pid>/status, as the lines
end on '\r', not on '\n'.
2023-09-10 16:46:59 +02:00
ff6a6e0e45 Use libCAslave.so as default library to use for downloading the device-controller-firmware. 2023-09-10 16:45:40 +02:00
afbce3b4ea Add new dc-lib 2023-09-09 15:10:53 +02:00
9 changed files with 140 additions and 45 deletions

View File

@@ -15,7 +15,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
VERSION=1.3.2
VERSION=1.3.5
INCLUDEPATH += plugins

View File

@@ -97,7 +97,7 @@ int main(int argc, char *argv[]) {
QCommandLineOption pluginNameOption(QStringList() << "plugin-name" << "plugin-name",
QCoreApplication::translate("main", "Name of dc-plugin."),
QCoreApplication::translate("main", "directory"));
QString const pluginNameDefault = "libCAmaster.so";
QString const pluginNameDefault = "libCAslave.so";
pluginNameOption.setDefaultValue(pluginNameDefault);
parser.addOption(pluginNameOption);

View File

@@ -131,9 +131,9 @@ MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *paren
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->updateStatus->installEventFilter(this);
m_startTimer = new QTimer(this);
connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update()));
@@ -308,9 +308,18 @@ void MainWindow::onEnableExit() {
ui->exit->setEnabled(true);
}
//bool MainWindow::eventFilter(QObject *obj, QEvent *ev) {
// if (obj == ui->updateStatus) {
// qCritical() << "REc. event for text edit" << ev->type();
// }
// return QMainWindow::eventFilter(obj, ev);
//}
void MainWindow::onRestartExitTimer() {
m_exitTimer->stop();
m_exitTimer->start(60 * 1000);
// ui->updateStatus->blockSignals(true);
}
void MainWindow::onQuit() {
@@ -320,7 +329,8 @@ void MainWindow::onQuit() {
}
void MainWindow::scrollDownTextEdit() {
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
Utils::printInfoMsg(QString("SCROLL-DOWN-TEXT_EDIT CALLED AT ")
+ QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
ui->updateStatus->setEnabled(true);
@@ -331,30 +341,37 @@ void MainWindow::scrollDownTextEdit() {
}
void MainWindow::onAppendText(QString text, QString suffix) {
qCritical() << "ON APPEND CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
Utils::printInfoMsg(QString("ON APPEND CALLED AT ")
+ QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
QString editText = ui->updateStatus->toPlainText();
if (!suffix.isNull() && suffix.size() > 0) {
//qInfo() << "TEXT" << text << "SUFFIX" << suffix;
if (suffix == Worker::UPDATE_STEP_SUCCESS || suffix == Worker::UPDATE_STEP_FAIL) {
editText += QString("\n").leftJustified(m_width-3, '=');
editText += " ";
ui->updateStatus->insertPlainText(QString("\n").leftJustified(m_width-3, '=') + " ");
// editText += QString("\n").leftJustified(m_width-3, '=');
// editText += " ";
}
QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix;
editText += add;
ui->updateStatus->insertPlainText(add);
// editText += add;
} else {
QString const &add = text.leftJustified(m_width-9);
editText += add;
ui->updateStatus->insertPlainText(add);
//editText += add;
}
Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts));
ui->updateStatus->setText(editText.trimmed());
// debug
// QString editText = ui->updateStatus->toPlainText();
// Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts));
// ui->updateStatus->setText(editText.trimmed());
scrollDownTextEdit();
}
void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
Utils::printInfoMsg(QString("ON REPLACE LAST (LIST) CALLED AT ")
+ QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
int const s = newTextLines.size();
if (s > 0) {
@@ -388,7 +405,8 @@ void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
}
void MainWindow::onReplaceLast(QString text, QString suffix) {
qCritical() << "ON REPLACE LAST CALLED AT" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
Utils::printInfoMsg(QString("ON REPLACE LAST (TEXT) CALLED AT ")
+ QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
QString editText = ui->updateStatus->toPlainText();
QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);

View File

@@ -21,6 +21,7 @@ class MainWindow : public QMainWindow {
protected:
void customEvent(QEvent *event) override;
// bool eventFilter(QObject *obj, QEvent *ev) override;
public:
MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent = nullptr);

51
plugins/interfaces.h Normal file → Executable file
View File

@@ -193,7 +193,7 @@ struct T_moduleCondition
uint8_t coinChecker; // EMP, OMP or mei-cashflow
uint8_t coinEscrow;
uint8_t mifareReader;
uint8_t mifareReader; // 0: unknown 1=OK 200=no response 201=wrong response 202: Reader reports HW-error
uint8_t creditTerm;
uint8_t coinReject;
@@ -818,7 +818,7 @@ public:
// --------------------------------------------- MIFARE -----------------------------------------------------
// ----------------------------------------------------------------------------------------------------------
// obsolete
virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0;
// retval 0=OK 1=error host buffer too small
/* data description, new fast version:
@@ -840,13 +840,16 @@ public:
virtual bool mif_readerIsOK(void) const =0;
virtual bool mif_cardAttached(void) const =0;
// not working! use mif_cardIsAttached() instead
virtual uint8_t mif_readResult(void) const =0;
// result: 0: unknown or still in progress
// 1: card read successful
// 2: reading error
// not working!
virtual QString mif_cardUID(void) const =0;
// not working
virtual uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const =0;
@@ -1289,7 +1292,7 @@ public:
// 1= wrong length 2=wrong start sign 5= wrong crc
// 6= slave: master cmd was wrong 7: slave: could not write/read data
// 8=timeout, got no response from slave
// 0,8 work, 1..6 not yet tested. 8 comes immed. and stays 8 until reconnect
// use for important and extended commands (print several templates, print ticket...)
virtual void log_startSupervision(void) const =0;
@@ -1299,6 +1302,7 @@ public:
// 0: started, in progress
// 1: done and OK
// 2: done and error
// not working properly, always 0
virtual bool log_getVaultData(uint8_t *data) const =0;
// get vault record in linear 8bit buffer with 384 byte
@@ -1343,6 +1347,37 @@ public:
// new functions from 8.9.23
virtual QString mif_getReaderType(void) const =0;
// return "SL025" if correct reader is connected
virtual void mif_getCardSize(uint8_t *cardSize, uint8_t *idLeng) const =0;
// cardSize=1k or 4kByte
// idLeng =4Byte or 7 byte
virtual char mif_getAtbCardData(uint8_t *buf, uint8_t maxBuffSiz) const =0;
// return complete buffer binary, just for test purpose
virtual bool mif_isValidAtbCard(void) const =0;
virtual uint32_t mif_getAtbCardCuNu(void) const =0;
virtual uint8_t mif_getAtbCardTyp(void) const =0;
// return 1=upper door card 1=lower door 3=printer-test 4=coin-test
// 0: not a valid atb2020 card
virtual QString mif_getAtbCardPerso(void) const =0;
// e.g. "PNsax001" used for personal number, name shortcode, card number
// free to use, can be set in AtbMcw23.exe tool
virtual void mif_getAtbCardExpire(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute) const =0;
signals:
virtual void hwapi_templatePrintFinished_OK(void) const=0;
virtual void hwapi_templatePrintFinished_Err(void) const=0;
@@ -1413,9 +1448,15 @@ signals:
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.1"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.2"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.3"
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.4"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.4"
// 8.9.2023 two new functions (end of file) for mifare test
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.5"
// 18.9.2023 major improvements for DC data exchange
// verification of door and cash box signals
// intensive verification of Json-Programming Master-Slave (PTU to DC), 100% ok
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.6"
// 20.9.2023: speeding up door and cash box signals
Q_DECLARE_INTERFACE(hwinf, HWINF_iid)

BIN
plugins/libCAmaster.so Normal file → Executable file

Binary file not shown.

View File

@@ -14,9 +14,9 @@
#include <QRegExp>
#include <QApplication>
//#include <iostream>
//#include <fstream>
//#include <ctime>
#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
#include "unistd.h"
#endif
#include "plugins/interfaces.h"
@@ -40,6 +40,8 @@ static const QMap<QString, int> baudrateMap = {
{"57600" , 4}, {"115200" , 5}
};
QPluginLoader Update::pluginLoader;
hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
hwinf *hw = nullptr;
if (plugInDir.exists()) {
@@ -48,7 +50,8 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
QFileInfo info(pluginLibName);
if (info.exists()) {
pluginLibName = plugInDir.absoluteFilePath(pluginLibName);
static QPluginLoader pluginLoader(pluginLibName);
pluginLoader.setFileName(pluginLibName);
// static QPluginLoader pluginLoader(pluginLibName);
if (!pluginLoader.load()) {
qCritical() << "in directory" << plugInDir.absolutePath();
qCritical() << "cannot load plugin" << pluginLoader.fileName();
@@ -80,6 +83,21 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
return hw;
}
bool Update::unloadDCPlugin() {
if (pluginLoader.unload()) {
qCritical() << "unloaded plugin" << pluginLoader.fileName();
// Note: will re-instantiate the library !
// QObject *rootObject = pluginLoader.instance();
// if (rootObject) {
// qCritical() << "reloaded plugin: root object again available";
// return false;
// }
// qCritical()unloaded plugin: root object gone";
return true;
}
return false;
}
Update::Update(hwinf *hw,
Worker *worker,
QString customerRepository,
@@ -724,6 +742,9 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
QString const &parentName = Utils::getParentName();
Utils::printInfoMsg(
QString("PARENT OF ATB-UPDATE-TOOL (ppid=%1) ").arg(getppid()) + parentName);
if (parentName == "ATBQT" || parentName == "systemd") {
// the tool was not called during 'service' ot during an automatic
// update procedure. and it was called explicitly with libCAmaster.so
@@ -732,6 +753,8 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
+ " IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
return false;
}
Utils::printInfoMsg(
QString("ATB-UPDATE-TOOL STARTED AS SLAVE OF ") + parentName);
} else
if (Utils::isATBQTRunning()) { // manual testing
if (m_pluginName.contains("master", Qt::CaseInsensitive)) {
@@ -739,12 +762,15 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
"ATBQT IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
return false;
}
Utils::printInfoMsg(
"ATB-UPDATE-TOOL STARTED AS SLAVE-SIBLING OF ATBQT-MASTER");
} else {
if (m_pluginName.contains("slave", Qt::CaseInsensitive)) {
Utils::printCriticalErrorMsg(
"ATB-UPDATE-TOOL CALLED WITH libCAslave.so ALTHOUGH MASTER");
return false;
}
Utils::printInfoMsg("ATB-UPDATE-TOOL STARTED AS MASTER");
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate),
m_baudrate,

View File

@@ -7,6 +7,7 @@
#include <QDir>
#include <QByteArray>
#include <QProcess>
#include <QPluginLoader>
#include "plugins/interfaces.h"
@@ -32,11 +33,14 @@ class Update : public QObject {
bool m_maintenanceMode;
bool m_dryRun;
static QPluginLoader pluginLoader;
public:
enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
enum class FileTypeJson {CONFIG=1, DEVICE=2, CASH=3, SERIAL=4, TIME=5, PRINTER=6};
static hwinf *loadDCPlugin(QDir const &plugInDir, QString const &fn);
static bool unloadDCPlugin();
static QStringList split(QString line, QChar sep = ',');

View File

@@ -2,13 +2,19 @@
#include "message_handler.h"
#include "git/git_client.h"
#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
#include "unistd.h"
#endif
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QRegularExpression>
#include <fstream>
int Utils::read1stLineOfFile(QString fileName) {
QFile f(fileName);
@@ -177,18 +183,15 @@ bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
QString Utils::getParentName() { // get name of parent process
QString ppid = QString("/proc/%1/status").arg(getppid());
QFile f(ppid);
if (f.exists()) {
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&f);
in.setCodec("UTF-8");
while(!in.atEnd()) {
// Name: ATBQT
QStringList line = in.readLine().split(':');
if (line.size() == 2) {
if (line[0].trimmed() == "Name") {
return line[1].trimmed();
}
std::ifstream f(ppid.toStdString().c_str());
if (f.is_open()) {
std::string next;
while (std::getline(f, next)) {
QString line = QString(next.c_str()).simplified();
if (line.startsWith("Name")) {
int const idx = line.indexOf(QChar(':'));
if (idx != -1) {
return line.mid(idx+1).trimmed();
}
}
}
@@ -203,17 +206,19 @@ bool Utils::isATBQTRunning() {
QDirIterator::Subdirectories);
while (it.hasNext()) {
QString const &nextStatusFile = it.next();
QFile f(nextStatusFile);
if (f.exists()) {
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&f);
in.setCodec("UTF-8");
while(!in.atEnd()) {
// Name: ATBQT
QStringList line = in.readLine().split(':');
if (line.size() == 2) {
if (line[0].trimmed() == "Name") {
if (line[1].trimmed() == "ATBQT") {
static const QRegularExpression re("^/proc/[0-9]{1,}/status");
QRegularExpressionMatch match = re.match(nextStatusFile);
if (match.hasMatch()) {
std::ifstream f(nextStatusFile.toStdString().c_str());
if (f.is_open()) {
std::string next;
while (std::getline(f, next)) {
QString line = QString(next.c_str()).simplified();
if (line.startsWith("Name")) {
int const idx = line.indexOf(QChar(':'));
if (idx != -1) {
QString const binary = line.mid(idx+1).trimmed();
if (binary == "ATBQT") {
return true;
}
}