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. # 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. # 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 #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 INCLUDEPATH += plugins

View File

@@ -97,7 +97,7 @@ int main(int argc, char *argv[]) {
QCommandLineOption pluginNameOption(QStringList() << "plugin-name" << "plugin-name", QCommandLineOption pluginNameOption(QStringList() << "plugin-name" << "plugin-name",
QCoreApplication::translate("main", "Name of dc-plugin."), QCoreApplication::translate("main", "Name of dc-plugin."),
QCoreApplication::translate("main", "directory")); QCoreApplication::translate("main", "directory"));
QString const pluginNameDefault = "libCAmaster.so"; QString const pluginNameDefault = "libCAslave.so";
pluginNameOption.setDefaultValue(pluginNameDefault); pluginNameOption.setDefaultValue(pluginNameDefault);
parser.addOption(pluginNameOption); 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("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3);
lst << QString("").leftJustified(m_width-3, '='); lst << QString("").leftJustified(m_width-3, '=');
ui->updateStatus->setText(lst.join('\n')); ui->updateStatus->setText(lst.join('\n'));
ui->updateStatus->setEnabled(true); ui->updateStatus->setEnabled(true);
// ui->updateStatus->installEventFilter(this);
m_startTimer = new QTimer(this); m_startTimer = new QTimer(this);
connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update())); connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update()));
@@ -308,9 +308,18 @@ void MainWindow::onEnableExit() {
ui->exit->setEnabled(true); 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() { void MainWindow::onRestartExitTimer() {
m_exitTimer->stop(); m_exitTimer->stop();
m_exitTimer->start(60 * 1000); m_exitTimer->start(60 * 1000);
// ui->updateStatus->blockSignals(true);
} }
void MainWindow::onQuit() { void MainWindow::onQuit() {
@@ -320,7 +329,8 @@ void MainWindow::onQuit() {
} }
void MainWindow::scrollDownTextEdit() { 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); ui->updateStatus->setEnabled(true);
@@ -331,30 +341,37 @@ void MainWindow::scrollDownTextEdit() {
} }
void MainWindow::onAppendText(QString text, QString suffix) { 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(); QString editText = ui->updateStatus->toPlainText();
if (!suffix.isNull() && suffix.size() > 0) { if (!suffix.isNull() && suffix.size() > 0) {
//qInfo() << "TEXT" << text << "SUFFIX" << suffix; //qInfo() << "TEXT" << text << "SUFFIX" << suffix;
if (suffix == Worker::UPDATE_STEP_SUCCESS || suffix == Worker::UPDATE_STEP_FAIL) { if (suffix == Worker::UPDATE_STEP_SUCCESS || suffix == Worker::UPDATE_STEP_FAIL) {
editText += QString("\n").leftJustified(m_width-3, '='); ui->updateStatus->insertPlainText(QString("\n").leftJustified(m_width-3, '=') + " ");
editText += " "; // editText += QString("\n").leftJustified(m_width-3, '=');
// editText += " ";
} }
QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix; QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix;
editText += add; ui->updateStatus->insertPlainText(add);
// editText += add;
} else { } else {
QString const &add = text.leftJustified(m_width-9); QString const &add = text.leftJustified(m_width-9);
editText += add; ui->updateStatus->insertPlainText(add);
//editText += add;
} }
Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts)); // debug
ui->updateStatus->setText(editText.trimmed()); // QString editText = ui->updateStatus->toPlainText();
// Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts));
// ui->updateStatus->setText(editText.trimmed());
scrollDownTextEdit(); scrollDownTextEdit();
} }
void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) { 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(); int const s = newTextLines.size();
if (s > 0) { if (s > 0) {
@@ -388,7 +405,8 @@ void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
} }
void MainWindow::onReplaceLast(QString text, 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(); QString editText = ui->updateStatus->toPlainText();
QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts); QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);

View File

@@ -21,6 +21,7 @@ class MainWindow : public QMainWindow {
protected: protected:
void customEvent(QEvent *event) override; void customEvent(QEvent *event) override;
// bool eventFilter(QObject *obj, QEvent *ev) override;
public: public:
MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent = nullptr); 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 coinChecker; // EMP, OMP or mei-cashflow
uint8_t coinEscrow; 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 creditTerm;
uint8_t coinReject; uint8_t coinReject;
@@ -818,7 +818,7 @@ public:
// --------------------------------------------- MIFARE ----------------------------------------------------- // --------------------------------------------- MIFARE -----------------------------------------------------
// ---------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------
// obsolete
virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0; virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0;
// retval 0=OK 1=error host buffer too small // retval 0=OK 1=error host buffer too small
/* data description, new fast version: /* data description, new fast version:
@@ -840,13 +840,16 @@ public:
virtual bool mif_readerIsOK(void) const =0; virtual bool mif_readerIsOK(void) const =0;
virtual bool mif_cardAttached(void) const =0; virtual bool mif_cardAttached(void) const =0;
// not working! use mif_cardIsAttached() instead
virtual uint8_t mif_readResult(void) const =0; virtual uint8_t mif_readResult(void) const =0;
// result: 0: unknown or still in progress // result: 0: unknown or still in progress
// 1: card read successful // 1: card read successful
// 2: reading error // 2: reading error
// not working!
virtual QString mif_cardUID(void) const =0; 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; 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 // 1= wrong length 2=wrong start sign 5= wrong crc
// 6= slave: master cmd was wrong 7: slave: could not write/read data // 6= slave: master cmd was wrong 7: slave: could not write/read data
// 8=timeout, got no response from slave // 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...) // use for important and extended commands (print several templates, print ticket...)
virtual void log_startSupervision(void) const =0; virtual void log_startSupervision(void) const =0;
@@ -1299,6 +1302,7 @@ public:
// 0: started, in progress // 0: started, in progress
// 1: done and OK // 1: done and OK
// 2: done and error // 2: done and error
// not working properly, always 0
virtual bool log_getVaultData(uint8_t *data) const =0; virtual bool log_getVaultData(uint8_t *data) const =0;
// get vault record in linear 8bit buffer with 384 byte // 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: signals:
virtual void hwapi_templatePrintFinished_OK(void) const=0; virtual void hwapi_templatePrintFinished_OK(void) const=0;
virtual void hwapi_templatePrintFinished_Err(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.1"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.2" //#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.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) 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 <QRegExp>
#include <QApplication> #include <QApplication>
//#include <iostream> #if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
//#include <fstream> #include "unistd.h"
//#include <ctime> #endif
#include "plugins/interfaces.h" #include "plugins/interfaces.h"
@@ -40,6 +40,8 @@ static const QMap<QString, int> baudrateMap = {
{"57600" , 4}, {"115200" , 5} {"57600" , 4}, {"115200" , 5}
}; };
QPluginLoader Update::pluginLoader;
hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) { hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
hwinf *hw = nullptr; hwinf *hw = nullptr;
if (plugInDir.exists()) { if (plugInDir.exists()) {
@@ -48,7 +50,8 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
QFileInfo info(pluginLibName); QFileInfo info(pluginLibName);
if (info.exists()) { if (info.exists()) {
pluginLibName = plugInDir.absoluteFilePath(pluginLibName); pluginLibName = plugInDir.absoluteFilePath(pluginLibName);
static QPluginLoader pluginLoader(pluginLibName); pluginLoader.setFileName(pluginLibName);
// static QPluginLoader pluginLoader(pluginLibName);
if (!pluginLoader.load()) { if (!pluginLoader.load()) {
qCritical() << "in directory" << plugInDir.absolutePath(); qCritical() << "in directory" << plugInDir.absolutePath();
qCritical() << "cannot load plugin" << pluginLoader.fileName(); qCritical() << "cannot load plugin" << pluginLoader.fileName();
@@ -80,6 +83,21 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
return hw; 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, Update::Update(hwinf *hw,
Worker *worker, Worker *worker,
QString customerRepository, QString customerRepository,
@@ -724,6 +742,9 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
QString const &parentName = Utils::getParentName(); QString const &parentName = Utils::getParentName();
Utils::printInfoMsg(
QString("PARENT OF ATB-UPDATE-TOOL (ppid=%1) ").arg(getppid()) + parentName);
if (parentName == "ATBQT" || parentName == "systemd") { if (parentName == "ATBQT" || parentName == "systemd") {
// the tool was not called during 'service' ot during an automatic // the tool was not called during 'service' ot during an automatic
// update procedure. and it was called explicitly with libCAmaster.so // 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"); + " IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
return false; return false;
} }
Utils::printInfoMsg(
QString("ATB-UPDATE-TOOL STARTED AS SLAVE OF ") + parentName);
} else } else
if (Utils::isATBQTRunning()) { // manual testing if (Utils::isATBQTRunning()) { // manual testing
if (m_pluginName.contains("master", Qt::CaseInsensitive)) { 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"); "ATBQT IS MASTER, BUT ATB-UPDATE-TOOL CALLED WITH libCAmaster.so");
return false; return false;
} }
Utils::printInfoMsg(
"ATB-UPDATE-TOOL STARTED AS SLAVE-SIBLING OF ATBQT-MASTER");
} else { } else {
if (m_pluginName.contains("slave", Qt::CaseInsensitive)) { if (m_pluginName.contains("slave", Qt::CaseInsensitive)) {
Utils::printCriticalErrorMsg( Utils::printCriticalErrorMsg(
"ATB-UPDATE-TOOL CALLED WITH libCAslave.so ALTHOUGH MASTER"); "ATB-UPDATE-TOOL CALLED WITH libCAslave.so ALTHOUGH MASTER");
return false; return false;
} }
Utils::printInfoMsg("ATB-UPDATE-TOOL STARTED AS MASTER");
if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), if ((serialOpened = openSerial(baudrateMap.value(m_baudrate),
m_baudrate, m_baudrate,

View File

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

View File

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