Compare commits
	
		
			62 Commits
		
	
	
		
			v1.3.12
			...
			v1.3.15-js
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 990d257b09 | |||
| dfbad69ab1 | |||
| 5f0c86ba19 | |||
| 3588b25e65 | |||
| 1f8b88b2b6 | |||
| 0050ea35d0 | |||
| 7e4c138d1b | |||
| 685568d4f6 | |||
| 14b4c035da | |||
| 90de2f415e | |||
| 3cc71cb69b | |||
| fef7533d00 | |||
| e93058cc6b | |||
| e65387aa60 | |||
| 904fa0374b | |||
| 4bf1bbe81f | |||
| 3ccdcbae51 | |||
| 8c50e6cf59 | |||
| 7e69846169 | |||
| 34c55c576c | |||
| 7c2c4d4b80 | |||
| f9f698fd15 | |||
| b4457d8815 | |||
| 3621777827 | |||
| 003bd0bf77 | |||
| 721c5dd7a5 | |||
| a24eb9fd8c | |||
| 24351b8342 | |||
| 4b3a39b0e6 | |||
| a44b780d93 | |||
| 19dfae9b56 | |||
| bef0d4fe12 | |||
| 72a2fc781c | |||
| fc264689b1 | |||
| fc587456d5 | |||
| a2b933ab71 | |||
| 7d0fdf4d6d | |||
| c2ce44c79b | |||
| 16a9556863 | |||
| 48896f97ec | |||
| 4486317cb2 | |||
| 6b9b88ea19 | |||
| 99a99d95a1 | |||
| d4ddbbee21 | |||
| 34e5189945 | |||
| c44c805238 | |||
| 196f1a730e | |||
| 7dc04c4422 | |||
| 5efac2619b | |||
| 9b0f741b9b | |||
| 81c5f8ee7e | |||
| 29e6a25e72 | |||
| 5abc057bda | |||
| 8aeb7ecfea | |||
| 4bb8e241b6 | |||
| 4469a23f9c | |||
| d1f795e2db | |||
| 6865056f4b | |||
| 37bd5c90d3 | |||
| fcba120dfa | |||
| 1d4f50fb9f | |||
| a78040a037 | 
@@ -39,6 +39,46 @@ DEFINES += QT_DEPRECATED_WARNINGS
 | 
			
		||||
#           Use 'git pull' instead of 'git fetch'.
 | 
			
		||||
#           Use 'git clone --filter=blob:none' instead of 'git clone' to speed
 | 
			
		||||
#           up cloning of customer repository.
 | 
			
		||||
# 1.3.13:   Fix: if the customer repository is corrupted, remove it and re-clone
 | 
			
		||||
#           the repository (without checking the ISMAS-trigger (WAIT-)button.
 | 
			
		||||
# 1.3.14:   Add additional check for sanity of customer repository using
 | 
			
		||||
#           "git fsck".
 | 
			
		||||
#           Stream-lined code of update process: massive refactoring.
 | 
			
		||||
#           Added functionality: If WAIT button is not active, then an existing
 | 
			
		||||
#           customer repository will be repaired, or a not existing repository
 | 
			
		||||
#           will be cloned. The process stops then.
 | 
			
		||||
#           However, if the WAIT button is active, the at least the commands in
 | 
			
		||||
#           opkg_commands will be executed. Changed files in the customer
 | 
			
		||||
#           repository will be worked on: tariff-files will be synced with the
 | 
			
		||||
#           local filesystem, json-files will be downloaded to firmware.
 | 
			
		||||
#           The device-controller firmware will be handled in a later version.
 | 
			
		||||
VERSION="1.3.15"
 | 
			
		||||
#           Bug fixes found during testing.
 | 
			
		||||
#           Don't disable Exit-button during update-process.
 | 
			
		||||
#           Removed worker-thread with an own event-loop: only the GUI thread
 | 
			
		||||
#           has an event loop. Tested JSON-downloads several times successfully
 | 
			
		||||
#           (using the slave lib where the CA helper tool was active as master).
 | 
			
		||||
#           Turned previous worker-object into its own thread, but without any
 | 
			
		||||
#           own event-loop (so it cannot block anything inside the CA-plugin).
 | 
			
		||||
 | 
			
		||||
# PLANNED TODOS:
 | 
			
		||||
#   1:  Das Repository wird repariert bwz. neu geklont. Unabhaengig vom WAIT.
 | 
			
		||||
#   2:  Wenn der WAIT-Button aktiv ist, dann wird ein Repository repariert (neu
 | 
			
		||||
#       geklont), aber zusaetzlich werden alle verfuegbaren Dateien als neu
 | 
			
		||||
#       angesehen und die entsprechenden Aktionen durchgefuehrt: tariff-files
 | 
			
		||||
#       spiegeln, json-files laden und dc laden. Also VORSICHT: das repository
 | 
			
		||||
#       muss in diesem fall wirklich in ordnung sein.
 | 
			
		||||
#   3:  Wurde keine Datei geaendert, kein initiales Clone und der WAIT-button
 | 
			
		||||
#       nicht aktiv, so (passiert natuerlich nichts) kann man davon ausgehen,
 | 
			
		||||
#       dass es sich um ein automatisches Update handelt. Dann koennte man im
 | 
			
		||||
#       ISMAS eine entsprechende Meldung anzeigen als Teil von SEND-LAST-VERSION.
 | 
			
		||||
#       Wenn der WAIT-button aktiv ist, dann werden zumindest die opkg-commands
 | 
			
		||||
#       ausgefuehrt.
 | 
			
		||||
#   4:  rsync: immer alle Dateien soiegeln (bis auf opkg-commands)
 | 
			
		||||
#   5:  Falls das Tool mal abstuerzt, dann einen Signal-Handler (fuer TERM)
 | 
			
		||||
#       installieren, sodass zumnidest SEND-LAST-VERSION mit rausgeht.
 | 
			
		||||
#   6:  rsync: explizites Binary, nicht das in busybox enthaltene.
 | 
			
		||||
#   7:  Ein ini-File oder sowas.
 | 
			
		||||
 | 
			
		||||
win32 {
 | 
			
		||||
    BUILD_DATE=$$system("date /t")
 | 
			
		||||
@@ -50,7 +90,6 @@ win32 {
 | 
			
		||||
 | 
			
		||||
GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
 | 
			
		||||
 | 
			
		||||
VERSION="1.3.11"
 | 
			
		||||
EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
 | 
			
		||||
 | 
			
		||||
INCLUDEPATH += plugins
 | 
			
		||||
@@ -63,6 +102,8 @@ DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\"
 | 
			
		||||
DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\"
 | 
			
		||||
DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\"
 | 
			
		||||
 | 
			
		||||
# keep comments, as /* fall through */
 | 
			
		||||
QMAKE_CXXFLAGS += -C
 | 
			
		||||
QMAKE_CXXFLAGS += -g
 | 
			
		||||
QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
 | 
			
		||||
@@ -71,14 +112,14 @@ contains( CONFIG, PTU5 ) {
 | 
			
		||||
    CONFIG += link_pkgconfig
 | 
			
		||||
    lessThan(QT_MAJOR_VERSION, 5):   PKGCONFIG += qextserialport
 | 
			
		||||
    QMAKE_CXXFLAGS += -O2 -std=c++17   # for GCC >= 4.7
 | 
			
		||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    ARCH = PTU5
 | 
			
		||||
    DEFINES+=PTU5
 | 
			
		||||
}
 | 
			
		||||
contains( CONFIG, PTU5_YOCTO ) {
 | 
			
		||||
    greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
 | 
			
		||||
    QMAKE_CXXFLAGS += -std=c++17   # for GCC >= 4.7
 | 
			
		||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    PTU5BASEPATH = /opt/devel/ptu5
 | 
			
		||||
    ARCH = PTU5
 | 
			
		||||
    DEFINES+=PTU5
 | 
			
		||||
@@ -92,7 +133,7 @@ contains( CONFIG, DesktopLinux ) {
 | 
			
		||||
    # QMAKE_CC = ccache $$QMAKE_CC
 | 
			
		||||
    # QMAKE_CXX = ccache $$QMAKE_CXX
 | 
			
		||||
    QMAKE_CXXFLAGS += -std=c++17
 | 
			
		||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
			
		||||
    linux-clang {  QMAKE_CXXFLAGS += -Qunused-arguments   }
 | 
			
		||||
    ARCH = DesktopLinux
 | 
			
		||||
    DEFINES+=DesktopLinux
 | 
			
		||||
@@ -109,8 +150,7 @@ SOURCES += \
 | 
			
		||||
        ismas/ismas_client.cpp \
 | 
			
		||||
        process/command.cpp \
 | 
			
		||||
        message_handler.cpp \
 | 
			
		||||
        worker.cpp \
 | 
			
		||||
        worker_thread.cpp
 | 
			
		||||
        worker.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
        update.h \
 | 
			
		||||
@@ -124,7 +164,6 @@ HEADERS += \
 | 
			
		||||
        process/command.h \
 | 
			
		||||
        message_handler.h \
 | 
			
		||||
        worker.h \
 | 
			
		||||
        worker_thread.h \
 | 
			
		||||
        plugins/interfaces.h
 | 
			
		||||
 | 
			
		||||
FORMS += \
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,11 @@ bool GitClient::gitCloneCustomerRepository() {
 | 
			
		||||
 | 
			
		||||
        Note: git v2.18 does not support treeless clones: --filter=tree:0.
 | 
			
		||||
     */
 | 
			
		||||
    QString gitCommand("git clone --filter=blob:none ");
 | 
			
		||||
 | 
			
		||||
    // Note: for some reason it is necessary to pass "--progress ---v",
 | 
			
		||||
    // otherwise QProcess returns an error of 128 = 0x80 for the command.
 | 
			
		||||
 | 
			
		||||
    QString gitCommand("git clone --progress -vvv --filter=blob:none ");
 | 
			
		||||
    gitCommand += m_repositoryPath;
 | 
			
		||||
    Command c(gitCommand);
 | 
			
		||||
 | 
			
		||||
@@ -79,19 +83,32 @@ bool GitClient::gitCloneCustomerRepository() {
 | 
			
		||||
        QString const result = c.getCommandResult();
 | 
			
		||||
        if (!result.isEmpty()) {
 | 
			
		||||
            // Cloning into 'customer_281'...\n
 | 
			
		||||
            static QRegularExpression re("(^\\s*Cloning\\s+into\\s+[']\\s*)(.*)(\\s*['].*$)");
 | 
			
		||||
            QRegularExpressionMatch match = re.match(result);
 | 
			
		||||
            if (match.hasMatch()) {
 | 
			
		||||
                if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
			
		||||
                    if (match.captured(2).trimmed() == m_customerNr) {
 | 
			
		||||
                        qInfo() << "CLONING" << m_repositoryPath << "OK";
 | 
			
		||||
                        return true;
 | 
			
		||||
            int customer = -1;
 | 
			
		||||
            int cloning = result.indexOf("Cloning", 0, Qt::CaseInsensitive);
 | 
			
		||||
            if (cloning != -1) {
 | 
			
		||||
                customer = result.indexOf("customer_", cloning, Qt::CaseInsensitive);
 | 
			
		||||
                if (customer != -1) {
 | 
			
		||||
                    QString customerNr = result.mid(customer);
 | 
			
		||||
                    static constexpr char const ch = '\'';
 | 
			
		||||
                    int i = customerNr.indexOf(QChar(ch));
 | 
			
		||||
                    if (i != -1) {
 | 
			
		||||
                        if ((customerNr = customerNr.mid(0, i)) == m_customerNr) {
 | 
			
		||||
                            qInfo() << "CLONING" << m_repositoryPath << "OK";
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                        Utils::printCriticalErrorMsg(
 | 
			
		||||
                            QString("ERROR CLONE RESULT HAS WRONG CUSTOMER-NR. (%1 != %2) CLONE_RESULT=%3")
 | 
			
		||||
                                .arg(customerNr)
 | 
			
		||||
                                .arg(m_customerNr)
 | 
			
		||||
                                .arg(result));
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Utils::printCriticalErrorMsg(
 | 
			
		||||
                QString("ERROR CLONE RESULT HAS WRONG FORMAT. rcc=%1 CLONE_RESULT=%2")
 | 
			
		||||
                    .arg(re.captureCount())
 | 
			
		||||
                QString("ERROR CLONE RESULT HAS WRONG FORMAT. CLONING=%1 CUSTOMER=%2 CLONE_RESULT=%3")
 | 
			
		||||
                    .arg(cloning)
 | 
			
		||||
                    .arg(customer)
 | 
			
		||||
                    .arg(result));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -262,6 +279,17 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
 | 
			
		||||
    return std::nullopt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GitClient::gitFsck() {
 | 
			
		||||
    bool r = false;
 | 
			
		||||
    if (QDir(m_customerRepository).exists()) {
 | 
			
		||||
        Command c("git fsck");
 | 
			
		||||
        if ((r = c.execute(m_customerRepository)) == false) {
 | 
			
		||||
            QString const &s = c.getCommandResult().trimmed();
 | 
			
		||||
            Utils::printCriticalErrorMsg(QString("GIT FSCK FAILED: %1").arg(s));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 Hat sich nichts geaendert, so werden auch keine Commits <>..<> angezeigt
 | 
			
		||||
 */
 | 
			
		||||
@@ -274,55 +302,61 @@ std::optional<QString> GitClient::gitPull() {
 | 
			
		||||
            QString const s = c.getCommandResult().trimmed();
 | 
			
		||||
            if (!s.isEmpty()) {
 | 
			
		||||
                QStringList lines = Update::split(s, '\n');
 | 
			
		||||
                worker()->CONSOLE(lines) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
 | 
			
		||||
                if (!lines.empty()) {
 | 
			
		||||
                    int zoneNr = Utils::read1stLineOfFile("/mnt/system_data/zone_nr");
 | 
			
		||||
                    m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
 | 
			
		||||
                    // lines can look like this:
 | 
			
		||||
                    // From https://git.mimbach49.de/GerhardHoffmann/customer_281
 | 
			
		||||
                    //   41ec581..5d25ac3  master     -> origin/master
 | 
			
		||||
                    //   ff10f57..43530a1  zg1/zone1  -> origin/zg1/zone1
 | 
			
		||||
                    //   6ed893f..5d9882c  zg1/zone2  -> origin/zg1/zone2
 | 
			
		||||
                    //   4384d17..77045d8  zg1/zone3  -> origin/zg1/zone3
 | 
			
		||||
                    //   89d2812..36a0d74  zg1/zone5  -> origin/zg1/zone5
 | 
			
		||||
                    bool found = false;
 | 
			
		||||
                    for (int i=0; i < lines.size(); ++i) {
 | 
			
		||||
                        if (lines.at(i).contains(m_branchName)) {
 | 
			
		||||
                            found = true;
 | 
			
		||||
                            // 409f198..6c22726  zg1/zone1  -> origin/zg1/zone1
 | 
			
		||||
                            static QRegularExpression re("(^\\s*)([0-9A-Fa-f]+..[0-9A-Fa-f]+)(.*$)");
 | 
			
		||||
                            QRegularExpressionMatch match = re.match(lines.at(i));
 | 
			
		||||
                            if (match.hasMatch()) {
 | 
			
		||||
                                if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
			
		||||
                                    return match.captured(2);
 | 
			
		||||
                    static const QRegularExpression alreadyUpToDate("^\\s*Already\\s+up\\s+to\\s+date.*$");
 | 
			
		||||
                    if (std::none_of(lines.cbegin(), lines.cend(),
 | 
			
		||||
                        [](QString const &s) { return s.contains(alreadyUpToDate); })) {
 | 
			
		||||
                        int zoneNr = Utils::read1stLineOfFile("/mnt/system_data/zone_nr");
 | 
			
		||||
                        m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
 | 
			
		||||
                        // lines can look like this:
 | 
			
		||||
                        // From https://git.mimbach49.de/GerhardHoffmann/customer_281
 | 
			
		||||
                        //   41ec581..5d25ac3  master     -> origin/master
 | 
			
		||||
                        //   ff10f57..43530a1  zg1/zone1  -> origin/zg1/zone1
 | 
			
		||||
                        //   6ed893f..5d9882c  zg1/zone2  -> origin/zg1/zone2
 | 
			
		||||
                        //   4384d17..77045d8  zg1/zone3  -> origin/zg1/zone3
 | 
			
		||||
                        //   89d2812..36a0d74  zg1/zone5  -> origin/zg1/zone5
 | 
			
		||||
                        bool found = false;
 | 
			
		||||
                        for (int i=0; i < lines.size(); ++i) {
 | 
			
		||||
                            if (lines.at(i).contains(m_branchName)) {
 | 
			
		||||
                                found = true;
 | 
			
		||||
                                // 409f198..6c22726  zg1/zone1  -> origin/zg1/zone1
 | 
			
		||||
                                static QRegularExpression re("(^\\s*)([0-9A-Fa-f]+..[0-9A-Fa-f]+)(.*$)");
 | 
			
		||||
                                QRegularExpressionMatch match = re.match(lines.at(i));
 | 
			
		||||
                                if (match.hasMatch()) {
 | 
			
		||||
                                    if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
			
		||||
                                        QString const matchCaptured = match.captured(2);
 | 
			
		||||
                                        worker()->CONSOLE(QStringList(matchCaptured)) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
 | 
			
		||||
                                        return matchCaptured;
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        QStringList lst(QString("(wrong capture count (%1)").arg(re.captureCount()));
 | 
			
		||||
                                        worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
                                    }
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    emit m_worker->showErrorMessage("git pull",
 | 
			
		||||
                                        QString("(wrong cap-count (%1)").arg(re.captureCount()));
 | 
			
		||||
                                    QStringList lst("no regex-match for commits");
 | 
			
		||||
                                    worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
                                }
 | 
			
		||||
                            } else {
 | 
			
		||||
                                emit m_worker->showErrorMessage("git pull",
 | 
			
		||||
                                    "no regex-match for commits");
 | 
			
		||||
                                Utils::printCriticalErrorMsg("NO REGEX MATCH FOR COMMITS");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!found) {
 | 
			
		||||
                        emit m_worker->showErrorMessage("git pull",
 | 
			
		||||
                            QString("unkown branch name ") + m_branchName);
 | 
			
		||||
                        Utils::printCriticalErrorMsg("UNKNOWN BRANCH NAME " + m_branchName);
 | 
			
		||||
                        if (!found) {
 | 
			
		||||
                            QStringList lst(QString("unknown branch name ") + m_branchName);
 | 
			
		||||
                            worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return "Already up to date";
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    emit m_worker->showErrorMessage("git pull",
 | 
			
		||||
                        QString("wrong format for result of 'git pull' ") + s);
 | 
			
		||||
                    Utils::printCriticalErrorMsg(QString("WRONG FORMAT FOR RESULT OF 'GIT FETCH' ") + s);
 | 
			
		||||
                    QStringList lst(QString("WRONG FORMAT FOR RESULT OF 'GIT PULL' ") + s);
 | 
			
		||||
                    worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // emit m_worker->showErrorMessage("git fetch", "empty result for 'git fetch'");
 | 
			
		||||
                Utils::printInfoMsg("EMPTY RESULT FOR 'GIT PULL'");
 | 
			
		||||
                QStringList lst("EMPTY RESULT FOR 'GIT PULL'");
 | 
			
		||||
                worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        emit m_worker->showErrorMessage("git pull", QString("repository ") + m_customerRepository + " does not exist");
 | 
			
		||||
        Utils::printCriticalErrorMsg(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
 | 
			
		||||
        QStringList lst(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
 | 
			
		||||
        worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
    return std::nullopt;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,10 +43,15 @@ class GitClient : public QObject {
 | 
			
		||||
 | 
			
		||||
    bool gitCloneAndCheckoutBranch();
 | 
			
		||||
 | 
			
		||||
    Worker *worker() { return m_worker; }
 | 
			
		||||
    Worker const *worker() const { return m_worker; }
 | 
			
		||||
 | 
			
		||||
    std::optional<QString> gitPull();
 | 
			
		||||
    std::optional<QStringList> gitDiff(QString const &commit);
 | 
			
		||||
    std::optional<QStringList> gitMerge();
 | 
			
		||||
 | 
			
		||||
    bool gitFsck();
 | 
			
		||||
 | 
			
		||||
    QString gitLastCommit(QString fileName);
 | 
			
		||||
    QStringList gitShowReason(QString branchName);
 | 
			
		||||
    static QString gitBlob(QString fileName);
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,12 @@ void IsmasClient::printDebugMessage(int port,
 | 
			
		||||
                                    QString const &clientIP,
 | 
			
		||||
                                    int clientPort,
 | 
			
		||||
                                    QString const &message) {
 | 
			
		||||
#if 0
 | 
			
		||||
    Q_UNUSED(port);
 | 
			
		||||
    Q_UNUSED(clientIP);
 | 
			
		||||
    Q_UNUSED(clientPort);
 | 
			
		||||
    Q_UNUSED(message);
 | 
			
		||||
#else
 | 
			
		||||
    qDebug().noquote()
 | 
			
		||||
        << "\n"
 | 
			
		||||
        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
			
		||||
@@ -64,12 +70,19 @@ void IsmasClient::printDebugMessage(int port,
 | 
			
		||||
        << "local address ..." << clientIP << "\n"
 | 
			
		||||
        << "local port ......" << clientPort << "\n"
 | 
			
		||||
        << message;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IsmasClient::printInfoMessage(int port,
 | 
			
		||||
                                   QString const &clientIP,
 | 
			
		||||
                                   int clientPort,
 | 
			
		||||
                                   QString const &message) {
 | 
			
		||||
#if 0
 | 
			
		||||
    Q_UNUSED(port);
 | 
			
		||||
    Q_UNUSED(clientIP);
 | 
			
		||||
    Q_UNUSED(clientPort);
 | 
			
		||||
    Q_UNUSED(message);
 | 
			
		||||
#else
 | 
			
		||||
    qInfo().noquote()
 | 
			
		||||
        << "\n"
 | 
			
		||||
        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
			
		||||
@@ -78,6 +91,7 @@ void IsmasClient::printInfoMessage(int port,
 | 
			
		||||
        << "local address ..." << clientIP << "\n"
 | 
			
		||||
        << "local port ......" << clientPort << "\n"
 | 
			
		||||
        << message;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void IsmasClient::printErrorMessage(int port,
 | 
			
		||||
@@ -301,7 +315,7 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
 | 
			
		||||
        // printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
 | 
			
		||||
        QString response(buf);
 | 
			
		||||
 | 
			
		||||
        if (int idx = response.indexOf("{\"error\":\"ISMAS is offline\"}")) {
 | 
			
		||||
@@ -376,16 +390,18 @@ QString IsmasClient::errorBackendNotConnected(QString const &info,
 | 
			
		||||
                             version.toStdString().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString IsmasClient::errorGitClone(int percent, QString const &info, QString const &version) {
 | 
			
		||||
QString IsmasClient::errorGitClone(QString const &info,
 | 
			
		||||
                                   QString const &version) {
 | 
			
		||||
    return updateNewsToIsmas("U0003",
 | 
			
		||||
                             percent,
 | 
			
		||||
                             m_progressInPercent,
 | 
			
		||||
                             RESULT_CODE::INSTALL_ERROR,
 | 
			
		||||
                             "CLONE CUSTOMER REPOSITORY FAILED",
 | 
			
		||||
                             info.toStdString().c_str(),
 | 
			
		||||
                             version.toStdString().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString IsmasClient::backendConnected(QString const &info, QString const &version) {
 | 
			
		||||
QString IsmasClient::backendConnected(QString const &info,
 | 
			
		||||
                                      QString const &version) {
 | 
			
		||||
    return updateNewsToIsmas("U0010",
 | 
			
		||||
                             m_progressInPercent,
 | 
			
		||||
                             RESULT_CODE::SUCCESS,
 | 
			
		||||
@@ -394,7 +410,8 @@ QString IsmasClient::backendConnected(QString const &info, QString const &versio
 | 
			
		||||
                             version.toStdString().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString IsmasClient::execOpkgCommand(QString const &info, QString const &version) {
 | 
			
		||||
QString IsmasClient::execOpkgCommand(QString const &info,
 | 
			
		||||
                                     QString const &version) {
 | 
			
		||||
    return updateNewsToIsmas("U0010",
 | 
			
		||||
                             m_progressInPercent,
 | 
			
		||||
                             RESULT_CODE::SUCCESS,
 | 
			
		||||
 
 | 
			
		||||
@@ -177,7 +177,7 @@ public:
 | 
			
		||||
    QString cloneAndCheckoutCustomerRepository(QString const &info, QString const &version = QString());   // clone and checkout customer repository
 | 
			
		||||
    QString checkoutBranch(QString const &info, QString const &version = QString());   // checkout branch
 | 
			
		||||
    QString errorBackendNotConnected(QString const &info, QString const &version = QString());   // checkout branch
 | 
			
		||||
    QString errorGitClone(int percent, QString const &info, QString const &version = QString());
 | 
			
		||||
    QString errorGitClone(QString const &info, QString const &version = QString());
 | 
			
		||||
    QString backendConnected(QString const &info, QString const &version = QString());
 | 
			
		||||
    QString updateTriggerSet(QString const &info, QString const &version = QString());
 | 
			
		||||
    QString errorUpdateTrigger(QString const &info, QString const &version = QString());
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								main.cpp
									
									
									
									
									
								
							@@ -64,24 +64,6 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
        setDebugLevel(LOG_NOTICE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
 | 
			
		||||
//#ifdef _POSIX_THREAD_PROCESS_SHARED
 | 
			
		||||
//    errno = 0;
 | 
			
		||||
//    int res = 0;
 | 
			
		||||
//    if ((res = sysconf(_SC_THREAD_PROCESS_SHARED)) < 0) {
 | 
			
		||||
//        if (errno != 0) {
 | 
			
		||||
//            qCritical() << "_POSIX_THREAD_PROCESS_SHARED NOT SUPPORTED"
 | 
			
		||||
//                        << strerror(errno);
 | 
			
		||||
//            exit(-1);
 | 
			
		||||
//        }
 | 
			
		||||
//    } else {
 | 
			
		||||
//        if (res == _POSIX_THREAD_PROCESS_SHARED) {
 | 
			
		||||
//            Utils::printInfoMsg("_POSIX_THREAD_PROCESS_SHARED SUPPORTED");
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
//#endif
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
    QCommandLineParser parser;
 | 
			
		||||
    parser.setApplicationDescription("Download tool for downloading device controller firmware, printer json-files and executing opkg-commands.");
 | 
			
		||||
    parser.addHelpOption();
 | 
			
		||||
@@ -101,6 +83,10 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
    pluginNameOption.setDefaultValue(pluginNameDefault);
 | 
			
		||||
    parser.addOption(pluginNameOption);
 | 
			
		||||
 | 
			
		||||
    QCommandLineOption noDownloadOption("no-psa-hardware-update",
 | 
			
		||||
        QCoreApplication::translate("main", "Do not update the PSA firmware (json, device-controller)."));
 | 
			
		||||
    parser.addOption(noDownloadOption);
 | 
			
		||||
 | 
			
		||||
    QCommandLineOption workingDirectoryOption(QStringList() << "working-directory" << "working-directory",
 | 
			
		||||
        QCoreApplication::translate("main", "working directory of update-script."),
 | 
			
		||||
        QCoreApplication::translate("main", "directory"));
 | 
			
		||||
@@ -130,6 +116,7 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
    QString plugInName = parser.value(pluginNameOption);
 | 
			
		||||
    QString workingDir = parser.value(workingDirectoryOption);
 | 
			
		||||
    bool const dryRun = parser.isSet(dryRunOption);
 | 
			
		||||
    bool const noUpdatePsaHardware = parser.isSet(noDownloadOption);
 | 
			
		||||
    bool const showYoctoVersion = parser.isSet(yoctoVersionOption);
 | 
			
		||||
    bool const showYoctoInstallStatus = parser.isSet(yoctoInstallStatusOption);
 | 
			
		||||
    bool const showExtendedVersion = parser.isSet(extendedVersionOption);
 | 
			
		||||
@@ -170,6 +157,7 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
    qInfo() << "plugInName ..............." << plugInName;
 | 
			
		||||
    qInfo() << "workingDir ..............." << workingDir;
 | 
			
		||||
    qInfo() << "dryRun ..................." << dryRun;
 | 
			
		||||
    qInfo() << "noUpdatePsaHardware ......" << noUpdatePsaHardware;
 | 
			
		||||
    qInfo() << "extended-version ........." << APP_EXTENDED_VERSION;
 | 
			
		||||
    //qInfo() << "yocto-version ............" << Worker::getATBUpdateToolYoctoVersion();
 | 
			
		||||
    //qInfo() << "yocto-install-status ....." << Worker::getATBUpdateToolYoctoInstallationStatus();
 | 
			
		||||
@@ -181,35 +169,17 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
#error "Only tested under UNIX/LINUX"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
 | 
			
		||||
    hw->dc_autoRequest(true);
 | 
			
		||||
    // hw->dc_openSerial(5, "115200", "ttymxc2", 1);
 | 
			
		||||
 | 
			
		||||
    Worker worker(customerNr,
 | 
			
		||||
                  machineNr,
 | 
			
		||||
                  zoneNr,
 | 
			
		||||
                  branchName,
 | 
			
		||||
                  plugInDir,
 | 
			
		||||
                  plugInName,
 | 
			
		||||
                  workingDir,
 | 
			
		||||
                  noUpdatePsaHardware,
 | 
			
		||||
                  dryRun);
 | 
			
		||||
 | 
			
		||||
    QString const customerNrStr(
 | 
			
		||||
        QString("customer_") + QString::number(customerNr).rightJustified(3, '0'));
 | 
			
		||||
 | 
			
		||||
    QScopedPointer<Update> update(
 | 
			
		||||
        new Update(hw,
 | 
			
		||||
                   &worker,
 | 
			
		||||
                   QDir::cleanPath(workingDir + QDir::separator() + customerNrStr),
 | 
			
		||||
                   customerNrStr,
 | 
			
		||||
                   branchName,
 | 
			
		||||
                   plugInName,
 | 
			
		||||
                   workingDir,
 | 
			
		||||
                   dryRun,
 | 
			
		||||
                   nullptr,
 | 
			
		||||
                   SERIAL_PORT,
 | 
			
		||||
                   "115200"));
 | 
			
		||||
 | 
			
		||||
    MainWindow mw(hw, &worker, update.get());
 | 
			
		||||
    MainWindow mw(&worker);
 | 
			
		||||
    worker.setMainWindow(&mw);
 | 
			
		||||
 | 
			
		||||
    mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										235
									
								
								mainwindow.cpp
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								mainwindow.cpp
									
									
									
									
									
								
							@@ -13,102 +13,14 @@
 | 
			
		||||
#include <QEvent>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if EMERGENCY_LEAVE_BL==1
 | 
			
		||||
static int step = 0;
 | 
			
		||||
 | 
			
		||||
void MainWindow::emergencyLeaveBL() {
 | 
			
		||||
    //
 | 
			
		||||
    qCritical() << __func__ << step;
 | 
			
		||||
    switch(step) {
 | 
			
		||||
    case 0:
 | 
			
		||||
        if (m_hw->dc_openSerial(5, "115200", "ttymxc2", 1)) {
 | 
			
		||||
            qCritical() << __func__ << "open ok";
 | 
			
		||||
            step++;
 | 
			
		||||
            QThread::msleep(2000);
 | 
			
		||||
            m_hw->dc_autoRequest(false);
 | 
			
		||||
            emit leaveBL();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        m_hw->bl_rebootDC();
 | 
			
		||||
        QThread::msleep(1000);
 | 
			
		||||
        qCritical() << __func__ << "reboot ok" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        step++;
 | 
			
		||||
        emit leaveBL();
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
    case 3:
 | 
			
		||||
    case 4:
 | 
			
		||||
    case 5:
 | 
			
		||||
    case 6:
 | 
			
		||||
        m_hw->bl_startBL();
 | 
			
		||||
        QThread::msleep(1000);
 | 
			
		||||
        qCritical() << __func__ << "start" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        step++;
 | 
			
		||||
        emit leaveBL();
 | 
			
		||||
        break;
 | 
			
		||||
    case 7:
 | 
			
		||||
    case 9:
 | 
			
		||||
    case 11:
 | 
			
		||||
    case 13:
 | 
			
		||||
    case 15:
 | 
			
		||||
        m_hw->bl_checkBL();
 | 
			
		||||
        qCritical() << __func__ << "check" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        QThread::msleep(1500);
 | 
			
		||||
        ++step;
 | 
			
		||||
        emit leaveBL();
 | 
			
		||||
        break;
 | 
			
		||||
    case 8:
 | 
			
		||||
    case 10:
 | 
			
		||||
    case 12:
 | 
			
		||||
    case 14:
 | 
			
		||||
    case 16:
 | 
			
		||||
        qCritical() << __func__ << "is Up..." << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        if (m_hw->bl_isUp()) {
 | 
			
		||||
            qCritical() << __func__ << "is Up...OK" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
            QThread::msleep(5000);
 | 
			
		||||
            step = 16;
 | 
			
		||||
        } else {
 | 
			
		||||
            qCritical() << __func__ << "is Up...NO" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        }
 | 
			
		||||
        ++step;
 | 
			
		||||
        emit leaveBL();
 | 
			
		||||
        break;
 | 
			
		||||
    case 17:
 | 
			
		||||
    case 18:
 | 
			
		||||
    case 19:
 | 
			
		||||
        qCritical() << __func__ << "stop" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
			
		||||
        m_hw->bl_stopBL();
 | 
			
		||||
        QThread::msleep(1000);
 | 
			
		||||
        //m_hw->dc_closeSerial();
 | 
			
		||||
        ++step;
 | 
			
		||||
        emit leaveBL();
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent)
 | 
			
		||||
MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
			
		||||
    : QMainWindow(parent)
 | 
			
		||||
    , ui(new Ui::MainWindow)
 | 
			
		||||
    , m_hw(hw)
 | 
			
		||||
    , m_worker(worker)
 | 
			
		||||
    , m_width(70)
 | 
			
		||||
    , m_progressRunning(false)
 | 
			
		||||
    , m_progressValue(0)
 | 
			
		||||
    , m_update(update)
 | 
			
		||||
    , m_updateStep(UpdateDcEvent::UpdateStep::NONE) {
 | 
			
		||||
 | 
			
		||||
#if EMERGENCY_LEAVE_BL==1
 | 
			
		||||
    QTimer *t = new QTimer(this);
 | 
			
		||||
    connect(t, SIGNAL(timeout()), this, SLOT(emergencyLeaveBL()));
 | 
			
		||||
    connect(this, SIGNAL(leaveBL()), this, SLOT(emergencyLeaveBL()), Qt::QueuedConnection);
 | 
			
		||||
    t->setSingleShot(true);
 | 
			
		||||
    t->start(1000);
 | 
			
		||||
    return;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    this->setStatusBar(new QStatusBar(this));
 | 
			
		||||
    QFont f;
 | 
			
		||||
    f.setStyleHint(QFont::Monospace);
 | 
			
		||||
@@ -138,7 +50,7 @@ MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *paren
 | 
			
		||||
    // ui->updateStatus->installEventFilter(this);
 | 
			
		||||
 | 
			
		||||
    m_startTimer = new QTimer(this);
 | 
			
		||||
    connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update()));
 | 
			
		||||
    connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(start()));
 | 
			
		||||
    m_startTimer->setSingleShot(true);
 | 
			
		||||
    m_startTimer->start(1000);
 | 
			
		||||
 | 
			
		||||
@@ -155,6 +67,8 @@ MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *paren
 | 
			
		||||
    connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString)));
 | 
			
		||||
    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)));
 | 
			
		||||
    connect(m_worker, SIGNAL(showStatusMessage(QString,QString)),this, SLOT(onShowStatusMessage(QString,QString)));
 | 
			
		||||
    connect(m_worker, SIGNAL(replaceLast(QString,QString)),this,SLOT(onReplaceLast(QString,QString)));
 | 
			
		||||
    connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString)));
 | 
			
		||||
}
 | 
			
		||||
@@ -178,22 +92,22 @@ void MainWindow::customEvent(QEvent *event) {
 | 
			
		||||
            case START_PROGRESS_LOOP: {
 | 
			
		||||
                m_progressRunning = true;
 | 
			
		||||
                ui->updateProgress->reset();
 | 
			
		||||
                m_progressValue = 10;
 | 
			
		||||
                QApplication::postEvent(this, new ProgressEvent(this, m_progressValue));
 | 
			
		||||
                // m_progressValue = 10;
 | 
			
		||||
                QApplication::postEvent(this, new ProgressEvent(this, 1));
 | 
			
		||||
            } break;
 | 
			
		||||
            case STOP_PROGRESS_LOOP: {
 | 
			
		||||
                m_progressRunning = false;
 | 
			
		||||
                m_progressValue -= 10;
 | 
			
		||||
                m_worker->setProgress(m_progressValue/10);
 | 
			
		||||
                // m_progressValue -= 10;
 | 
			
		||||
                // m_worker->setProgress(m_progressValue/10);
 | 
			
		||||
            } break;
 | 
			
		||||
            default: {
 | 
			
		||||
                    if (m_progressRunning) {
 | 
			
		||||
                        m_progressValue = progress;
 | 
			
		||||
                        ui->updateProgress->setValue(progress/10);
 | 
			
		||||
                        QApplication::postEvent(this, new ProgressEvent(this, progress+10));
 | 
			
		||||
                        QThread::msleep(500);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (m_progressRunning) {
 | 
			
		||||
                    // m_progressValue = progress;
 | 
			
		||||
                    ui->updateProgress->setValue(progress);
 | 
			
		||||
                    // ueberpruefen: hauptfenster schickt sich selber ein event
 | 
			
		||||
                    // QApplication::postEvent(this, new ProgressEvent(this, progress));
 | 
			
		||||
                    // QThread::msleep(500);
 | 
			
		||||
                }}
 | 
			
		||||
            }
 | 
			
		||||
        } else
 | 
			
		||||
        if (sender == m_worker) {
 | 
			
		||||
@@ -213,86 +127,6 @@ void MainWindow::customEvent(QEvent *event) {
 | 
			
		||||
        } else {
 | 
			
		||||
            qCritical() << "!!! UNKNOWN SENDER !!!";
 | 
			
		||||
        }
 | 
			
		||||
    } else
 | 
			
		||||
    if (event->type() == UpdateDcEvent::type()) {
 | 
			
		||||
        UpdateDcEvent *pevent = (UpdateDcEvent *)event;
 | 
			
		||||
        UpdateDcEvent::UpdateStep const updateStep = pevent->updateStep();
 | 
			
		||||
        QObject const *sender = pevent->sender();
 | 
			
		||||
        if (sender == m_worker) {
 | 
			
		||||
            QDateTime const &recv = QDateTime::currentDateTime();
 | 
			
		||||
            QDateTime const &send = pevent->sendDateTime();
 | 
			
		||||
            qint64 const delay = recv.toMSecsSinceEpoch() - send.toMSecsSinceEpoch();
 | 
			
		||||
            switch(updateStep) {
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::NONE:
 | 
			
		||||
                break;
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::DC_REBOOT: {
 | 
			
		||||
                m_hw->bl_rebootDC();
 | 
			
		||||
                QString msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
 | 
			
		||||
                          + QString(": reset device controller (delay=%1ms").arg(delay);
 | 
			
		||||
                emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                m_updateStep = UpdateDcEvent::UpdateStep::DC_REBOOT;
 | 
			
		||||
            } break;
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::BL_START: {
 | 
			
		||||
                QString const &msg = recv.toString(Qt::ISODateWithMs)
 | 
			
		||||
                    + QString(": start bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                m_hw->bl_startBL();
 | 
			
		||||
                if (pevent->count() == BL_START_COUNT) {
 | 
			
		||||
                    m_updateStep = UpdateDcEvent::UpdateStep::BL_START;
 | 
			
		||||
                }
 | 
			
		||||
            } break;
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::BL_CHECK: {
 | 
			
		||||
                if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) {
 | 
			
		||||
                    QString const &msg = recv.toString(Qt::ISODateWithMs)
 | 
			
		||||
                        + QString(": request bootloader version (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                    emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                    Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                    m_hw->bl_checkBL();
 | 
			
		||||
                    //m_updateStep = UpdateDcEvent::UpdateStep::BL_CHECK;
 | 
			
		||||
                }
 | 
			
		||||
            } break;
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::BL_IS_UP: {
 | 
			
		||||
                QString msg = recv.toString(Qt::ISODateWithMs)
 | 
			
		||||
                    + QString(": check running bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) {
 | 
			
		||||
                    if (m_hw->bl_isUp()) {
 | 
			
		||||
                        msg = recv.toString(Qt::ISODateWithMs)
 | 
			
		||||
                            + QString(": bootloader running (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                        emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                        Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                        m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_UP;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        msg = recv.toString(Qt::ISODateWithMs)
 | 
			
		||||
                            + QString(": bootloader stop requested (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                        emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                        Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                        if (m_updateStep == UpdateDcEvent::UpdateStep::BL_STOP) {
 | 
			
		||||
                            msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
 | 
			
		||||
                                    + QString(": bootloader down (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                            emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                            Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                            m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_DOWN;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } break;
 | 
			
		||||
            case UpdateDcEvent::UpdateStep::BL_STOP: {
 | 
			
		||||
                QString const &msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs)
 | 
			
		||||
                    + QString(": stop bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay);
 | 
			
		||||
                emit m_worker->showStatusMessage("dc update", msg);
 | 
			
		||||
                Utils::printInfoMsg(msg.toUpper());
 | 
			
		||||
                //if (m_bootLoaderIsUp) {
 | 
			
		||||
                m_hw->bl_stopBL();
 | 
			
		||||
                m_updateStep = UpdateDcEvent::UpdateStep::BL_STOP;
 | 
			
		||||
                //}
 | 
			
		||||
            } break;
 | 
			
		||||
            default: ;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QThread::yieldCurrentThread();
 | 
			
		||||
@@ -310,13 +144,6 @@ 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);
 | 
			
		||||
@@ -327,8 +154,18 @@ void MainWindow::onRestartExitTimer() {
 | 
			
		||||
 | 
			
		||||
void MainWindow::onQuit() {
 | 
			
		||||
    m_exitTimer->stop();
 | 
			
		||||
    qCritical() << QString("ON QUIT: EXIT CODE %1").arg(m_worker->returnCode());
 | 
			
		||||
    qApp->exit(m_worker->returnCode());
 | 
			
		||||
    int errorCode = 0;
 | 
			
		||||
 | 
			
		||||
    qCritical()
 | 
			
		||||
        << QString("ON QUIT: CURRENT STEP %1")
 | 
			
		||||
            .arg(m_worker->getSmap()[m_worker->currentStep()]);
 | 
			
		||||
 | 
			
		||||
    // TODO: replace SEND_LAST_VERSION with UPDATE_SUCCEEDED
 | 
			
		||||
    if (m_worker->currentStep() != Worker::UPDATE_STEP::SEND_LAST_VERSION) {
 | 
			
		||||
        errorCode = -1;
 | 
			
		||||
    }
 | 
			
		||||
    qCritical() << QString("ON QUIT: EXIT CODE %1").arg(errorCode);
 | 
			
		||||
    qApp->exit(errorCode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::scrollDownTextEdit() {
 | 
			
		||||
@@ -448,3 +285,21 @@ void MainWindow::onShowErrorMessage(QString title, QString text) {
 | 
			
		||||
void MainWindow::onShowStatusMessage(QString title, QString text) {
 | 
			
		||||
    onShowMessage(title, text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::onShowErrorMessage(QStringList lst) {
 | 
			
		||||
    if (lst.size() >= 2) {
 | 
			
		||||
        onShowMessage(lst.at(0), lst.at(1));
 | 
			
		||||
    }
 | 
			
		||||
    if (lst.size() == 1) {
 | 
			
		||||
        onShowMessage(lst.at(0), "");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::onShowStatusMessage(QStringList lst) {
 | 
			
		||||
    if (lst.size() >= 2) {
 | 
			
		||||
        onShowMessage(lst.at(0), lst.at(1));
 | 
			
		||||
    }
 | 
			
		||||
    if (lst.size() == 1) {
 | 
			
		||||
        onShowMessage(lst.at(0), "");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								mainwindow.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								mainwindow.h
									
									
									
									
									
								
							@@ -21,10 +21,9 @@ 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);
 | 
			
		||||
    MainWindow(Worker *worker, QWidget *parent = nullptr);
 | 
			
		||||
    ~MainWindow();
 | 
			
		||||
 | 
			
		||||
    static const int START_PROGRESS_LOOP = -1;
 | 
			
		||||
@@ -34,11 +33,6 @@ public:
 | 
			
		||||
    static const int BL_IS_UP_COUNT = 5;
 | 
			
		||||
    static const int BL_STOP_COUNT = 5;
 | 
			
		||||
 | 
			
		||||
    int progressValue() const { return m_progressValue; }
 | 
			
		||||
    hwinf *getPlugin() { return m_hw; }
 | 
			
		||||
    hwinf const *getPlugin() const { return m_hw; }
 | 
			
		||||
    Update *getUpdate() { return m_update; }
 | 
			
		||||
    Update const *getUpdate() const { return m_update; }
 | 
			
		||||
    UpdateDcEvent::UpdateStep updateStep() const { return m_updateStep; }
 | 
			
		||||
    void setUpdateStep(UpdateDcEvent::UpdateStep updateStep) { m_updateStep = updateStep; }
 | 
			
		||||
 | 
			
		||||
@@ -48,6 +42,8 @@ public slots:
 | 
			
		||||
    void onReplaceLast(QString, QString suffix = "");
 | 
			
		||||
    void onShowErrorMessage(QString, QString);
 | 
			
		||||
    void onShowStatusMessage(QString, QString);
 | 
			
		||||
    void onShowErrorMessage(QStringList);
 | 
			
		||||
    void onShowStatusMessage(QStringList);
 | 
			
		||||
    void onStopStartTimer();
 | 
			
		||||
    void onRestartExitTimer();
 | 
			
		||||
    void onEnableExit();
 | 
			
		||||
@@ -70,14 +66,12 @@ private:
 | 
			
		||||
    void onShowMessage(QString, QString);
 | 
			
		||||
 | 
			
		||||
    Ui::MainWindow *ui;
 | 
			
		||||
    hwinf *m_hw;
 | 
			
		||||
    Worker *m_worker;
 | 
			
		||||
    int const m_width;
 | 
			
		||||
    QTimer *m_startTimer;
 | 
			
		||||
    QTimer *m_exitTimer;
 | 
			
		||||
    bool m_progressRunning;
 | 
			
		||||
    int m_progressValue;
 | 
			
		||||
    Update *m_update;
 | 
			
		||||
    //int m_progressValue;
 | 
			
		||||
    UpdateDcEvent::UpdateStep m_updateStep;
 | 
			
		||||
};
 | 
			
		||||
#endif // MAINWINDOW_H
 | 
			
		||||
 
 | 
			
		||||
@@ -344,7 +344,41 @@ struct T_devices
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct T_chg_Tub
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    uint8_t  tubeLevel[8];      // [0]=nr coins of lowest value
 | 
			
		||||
    uint8_t  tubeFull[8];       // 1=full  0 else
 | 
			
		||||
    uint16_t tubeValues[8];     // in cent [0]=lowest value 5c or 10cent
 | 
			
		||||
    uint16_t tubeFilled[8];     // nr of every coin inserted
 | 
			
		||||
    uint16_t tubeDispens[8];     // nr of every coin dispensed
 | 
			
		||||
    // 64 byte
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct T_changer
 | 
			
		||||
{
 | 
			
		||||
    // Fixdata from Coin Changer
 | 
			
		||||
    uint8_t setup;  	// always 1
 | 
			
		||||
    uint8_t state;  	// step of state machine
 | 
			
		||||
        // 0..12 like EMP, 13...30 for coin dispense
 | 
			
		||||
 | 
			
		||||
    uint8_t level;      // mdb-level, always 3
 | 
			
		||||
    uint16_t countryCode;
 | 
			
		||||
    uint8_t scale;
 | 
			
		||||
    uint8_t decimals;
 | 
			
		||||
    uint8_t coinSetup[16];  // [0]=lowest coin, multiply with scale
 | 
			
		||||
    uint16_t intendedAcceptance;    //bitwise 0,1 1=accept coin, came from master
 | 
			
		||||
    uint8_t tokenChannel;
 | 
			
		||||
    uint8_t pollingRunning;		// 1: emp is polled  0:not
 | 
			
		||||
    uint8_t paymentRunning;	// 1: coins are accepted
 | 
			
		||||
    uint16_t denomination[16];
 | 
			
		||||
    uint16_t availableTubes; //bitwise 0,1 1=av. bit0 = lowest coin value
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct T_bna
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class hwinf
 | 
			
		||||
{
 | 
			
		||||
@@ -1373,7 +1407,183 @@ public:
 | 
			
		||||
    virtual void mif_getAtbCardExpire(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute) const =0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
    //    Device-Controller-Bootloader convenient version 21.09.2023
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // use this to jump to BL:
 | 
			
		||||
    //void hwapi::bl_rebootDC(void) const
 | 
			
		||||
 | 
			
		||||
    // use this to start BL:
 | 
			
		||||
    // void hwapi::bl_startBL(void) const
 | 
			
		||||
 | 
			
		||||
    // call this in order to get response from BL:
 | 
			
		||||
    //void hwapi::bl_checkBL(void) const
 | 
			
		||||
 | 
			
		||||
    // evaluate BL response:
 | 
			
		||||
    //bool hwapi::bl_isUp(void) const
 | 
			
		||||
 | 
			
		||||
    // 29.9.23: new: "completeStart" function, replaces bl_rebootDC(), bl_startBL() and bl_checkBL()
 | 
			
		||||
    // result can be verified with bl_isUp() as before
 | 
			
		||||
    virtual bool bl_completeStart(void) const =0;
 | 
			
		||||
        // must be used in DC's normal operation
 | 
			
		||||
 | 
			
		||||
    // select binfile-name in GUI
 | 
			
		||||
 | 
			
		||||
    // send binfile-name to BL-processor:
 | 
			
		||||
    virtual bool bl_storeFirmware(QString fileName) const =0;
 | 
			
		||||
        // load binary file 3x and compare
 | 
			
		||||
        // return true if loaded correctly
 | 
			
		||||
        // return false:  error, could not load correctly
 | 
			
		||||
 | 
			
		||||
    // request the number of blocks for this file
 | 
			
		||||
    virtual uint16_t bl_getNrOfFirmwareBlocks(void) const =0;
 | 
			
		||||
        // size of the loaded bin file in 64byte blocks
 | 
			
		||||
        // call after bl_storeFirmware()
 | 
			
		||||
 | 
			
		||||
    // call the next two function's repetitive with "blockNumber"=0,1,2,3....."bl_getNrOfFirmwareBlocks()"
 | 
			
		||||
 | 
			
		||||
    virtual bool bl_blockAutoLoad(uint16_t blockNumber) const =0;
 | 
			
		||||
        // call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()"
 | 
			
		||||
        //the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!)
 | 
			
		||||
        // but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!!
 | 
			
		||||
        // data will be sent to DC, if neccesary addr will be sent additionally
 | 
			
		||||
        // if neccesary sending will automatically repeat up to 3times
 | 
			
		||||
        // retval: false if blockNumber>4095, true else
 | 
			
		||||
 | 
			
		||||
    // check out this response after every block-sending, wait until >0!!!
 | 
			
		||||
    virtual int8_t bl_blockAutoResponse(void) const =0;
 | 
			
		||||
        // 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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // finally call:
 | 
			
		||||
    // void hwapi::bl_stopBL(void) const
 | 
			
		||||
    // -------------- end of bootloader ---------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // new from 28.9.23 and earliest from DC version 4.45
 | 
			
		||||
    // get all versions of the DC-Jsons
 | 
			
		||||
    virtual void sys_requestJsonVersions(uint8_t  jsonNr) const =0;
 | 
			
		||||
        // send one request for every single version
 | 
			
		||||
        // jsonNr=1...36, 1=config file (cust.Nr) 2=devices  3=cash  4=res.
 | 
			
		||||
        //      5=printer template 1 ..... 36= template 32
 | 
			
		||||
 | 
			
		||||
    virtual void sys_getJsonVersions(uint8_t  jsonNr, char *versionString) const =0;
 | 
			
		||||
        // jsonNr=1...36, 1=config file (cust.Nr) 2=devices  3=cash  4=res.
 | 
			
		||||
        //      5=printer template 1 ..... 36= template 32
 | 
			
		||||
        // length of buffer is always 16 byte
 | 
			
		||||
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
    //   Coin Changer
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // find above (same as for coin checker (EMP)):
 | 
			
		||||
 | 
			
		||||
    // mdb_switchPower(true);       // power on/off
 | 
			
		||||
    // cash_startPayment(amount_cent); // start polling, enable coins, changer turns to green
 | 
			
		||||
 | 
			
		||||
    // getInsertedAmount()
 | 
			
		||||
    // getLastInsertedCoin()
 | 
			
		||||
    // getAllInsertedCoins(uint16_t *types, uint16_t *values)
 | 
			
		||||
        // all inserted coins of this past transaction are stored, max 64
 | 
			
		||||
 | 
			
		||||
    // cash_stopPayment();      // and wait for further command (changer blinks yellow)
 | 
			
		||||
    // cash_cancelPayment();    // and return complete paid amount
 | 
			
		||||
 | 
			
		||||
    // after ticket/goods issue:
 | 
			
		||||
    // vend_success()
 | 
			
		||||
        // conclude payment process, keep all coins. Printing was successful
 | 
			
		||||
        // return change (payment above start-amount), so it works only if
 | 
			
		||||
        //  Payment was started with real vending price (pre selection).
 | 
			
		||||
        // if payment was started with maximum price (for direct coin insertion)
 | 
			
		||||
        // then use "changer_returnCoins()", not vend_success()
 | 
			
		||||
 | 
			
		||||
    // vend_failed()
 | 
			
		||||
        // conclude payment process and return complete paid amount
 | 
			
		||||
 | 
			
		||||
    // also valid for changer:
 | 
			
		||||
    // emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0;
 | 
			
		||||
        // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
 | 
			
		||||
        // tokenChannel 0...31: if this signal comes from emp then a token was inserted
 | 
			
		||||
        // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
 | 
			
		||||
 | 
			
		||||
    virtual void changer_returnCoins(uint32_t amountInCent) const =0;
 | 
			
		||||
 | 
			
		||||
    virtual void changer_requestChangeResult(void) const =0;
 | 
			
		||||
 | 
			
		||||
    virtual uint8_t changer_getChangeResult(uint32_t *returnedAmount) const =0;
 | 
			
		||||
        // get result of coin dispensing
 | 
			
		||||
        // receivedData[0]: 0: not yet started      1:amount returned
 | 
			
		||||
        //                  2:only partial return   3: no return possible
 | 
			
		||||
        // receivedData[2,3,4,5]: returned amount
 | 
			
		||||
 | 
			
		||||
    virtual void changer_getAllParameters(struct T_changer *mw) const =0;
 | 
			
		||||
        // requested automatically with 23, same like EMP
 | 
			
		||||
 | 
			
		||||
    virtual void changer_requestTubelevel(void) const =0;
 | 
			
		||||
 | 
			
		||||
    virtual void changer_getTubelevel(struct T_chg_Tub *tubLevel) const =0;
 | 
			
		||||
        // don't use tubeDispens[], it's not yet correct!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
    //   bank note acceptor
 | 
			
		||||
    // ------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // already defiened functions applying for BNA as well:
 | 
			
		||||
    // mdb_switchPower(true);       // power on/off
 | 
			
		||||
 | 
			
		||||
    // bank notes are integrated in the normal transaction process, so use the usual functions to run a vending cycle:
 | 
			
		||||
    // cash_startPayment(amount_cent); // start polling, enable bills, reader shows green
 | 
			
		||||
    // getInsertedAmount()
 | 
			
		||||
    // cash_stopPayment();
 | 
			
		||||
    // cash_cancelPayment();
 | 
			
		||||
    // vend_success()
 | 
			
		||||
    // vend_failed()
 | 
			
		||||
 | 
			
		||||
    virtual void bna_sendSettings(uint16_t notesToAccept, uint16_t parameters,
 | 
			
		||||
                                  uint16_t *billDenomination,
 | 
			
		||||
                                  uint32_t acceptanceLimit) const =0;
 | 
			
		||||
        // notesToAccept: bit0=bill1 (lowest donomination)  bitH=accept  bit L = deny
 | 
			
		||||
        // parameters: e.g. use escrow function for some notes
 | 
			
		||||
        // billDenomination = array of 16 bill values (e.g. 5, 10, 20...)
 | 
			
		||||
        // these can be set alternatively by Json-File DC2C_cash.json
 | 
			
		||||
        // acceptanceLimit: device will stop acceptance once this amount is reached and
 | 
			
		||||
        //          optionally keep last bill in escrow until vend_success()
 | 
			
		||||
        //          is called (put bill to stacker) or vend_failed() is called (return bill)
 | 
			
		||||
 | 
			
		||||
    virtual void bna_setCurrentAcceptance(uint16_t notesToAccept) const =0;
 | 
			
		||||
        // can be used to block notes dynamically, example: from now only 5€ bills are allowed (if only 3€ are to be paid)
 | 
			
		||||
        // only valid till next start-payment. Cannot add notes which are not activated in Json
 | 
			
		||||
 | 
			
		||||
    virtual void bna_requestParameters(void) const =0;
 | 
			
		||||
        // send command to DC in order to get static invariable device parameters like currency
 | 
			
		||||
        // device must be powered and polled to get these
 | 
			
		||||
 | 
			
		||||
    virtual bool bna_getAllParameters(struct T_bna *bna) const =0;
 | 
			
		||||
        // get all constant data from reader (e.g. currency)
 | 
			
		||||
        // and actual Host-Settings (sent with bna_sendSettings() or json)
 | 
			
		||||
        // retval = true if data are valid
 | 
			
		||||
 | 
			
		||||
    virtual void bna_requestCurrentNotes(void) const =0;
 | 
			
		||||
        // send command to DC in order to get transaction data
 | 
			
		||||
 | 
			
		||||
    virtual uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const =0;
 | 
			
		||||
        // returns number of collected bank notes since start-command (current transaction)
 | 
			
		||||
        //  latestBill: last accepted bank note, value in cent
 | 
			
		||||
        //  currentNotes an array with up to 16 (further) notes collected
 | 
			
		||||
 | 
			
		||||
    virtual void bna_requestStackerLevel(void) const =0;
 | 
			
		||||
 | 
			
		||||
    virtual uint16_t bna_getStackerLevel(uint32_t *amountInStacker, uint16_t *countOfBills) const =0;
 | 
			
		||||
        // return val: nr of bills in stacker
 | 
			
		||||
        // countOfBills: array of up to 16 sums,    countOfBills[0]=nr of 5€-bills in stacker
 | 
			
		||||
        //                                          countOfBills[1] for 10€   and so on
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1395,8 +1605,6 @@ signals:
 | 
			
		||||
    virtual void hwapi_payCancelled(void) const=0;
 | 
			
		||||
    virtual void hwapi_coinProcessJustStopped(void) const=0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // new from 2023.06.12
 | 
			
		||||
    virtual void hwapi_doorServiceDoorOpened(void) const=0;
 | 
			
		||||
    virtual void hwapi_doorVaultDoorOpened(void) const=0;
 | 
			
		||||
    virtual void hwapi_doorCoinBoxRemoved(void) const=0;
 | 
			
		||||
@@ -1454,9 +1662,17 @@ signals:
 | 
			
		||||
    // 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"
 | 
			
		||||
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.6"
 | 
			
		||||
    // 20.9.2023: speeding up door and cash box signals
 | 
			
		||||
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.7"
 | 
			
		||||
    // 26.09.2023: added improved DC-bootloader files
 | 
			
		||||
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.8"
 | 
			
		||||
// 28.09.2023: added version request of DC-Json-Files
 | 
			
		||||
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.0"
 | 
			
		||||
    // 10.10.2023: added coin changer
 | 
			
		||||
 | 
			
		||||
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.1"
 | 
			
		||||
// 20.10.2023: added bill validator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Q_DECLARE_INTERFACE(hwinf, HWINF_iid)
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -4,6 +4,7 @@
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QRegularExpression>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
 | 
			
		||||
Command::Command(QString const &command, int start_timeout, int finish_timeout)
 | 
			
		||||
    : m_command(command.trimmed())
 | 
			
		||||
@@ -65,6 +66,8 @@ bool Command::execute(QString workingDirectory, QStringList args) {
 | 
			
		||||
        p->start(m_command);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
 | 
			
		||||
    if (p->waitForStarted(m_waitForStartTimeout)) {
 | 
			
		||||
        qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory();
 | 
			
		||||
        if (p->state() == QProcess::ProcessState::Running) {
 | 
			
		||||
@@ -80,31 +83,41 @@ bool Command::execute(QString workingDirectory, QStringList args) {
 | 
			
		||||
                qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory();
 | 
			
		||||
                if (p->exitStatus() == QProcess::NormalExit) {
 | 
			
		||||
                    if ((m_exitCode = p->exitCode()) == 0) {
 | 
			
		||||
                        qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
                        qDebug() << "EXECUTED" << m_command
 | 
			
		||||
                                 << QString("(runtime %1ms)").arg(end-start)
 | 
			
		||||
                                 << "with code" << m_exitCode
 | 
			
		||||
                                 << "IN" << p->workingDirectory();
 | 
			
		||||
                        return true;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
                        qCritical() << "EXECUTED" << m_command
 | 
			
		||||
                                    << QString("(runtime %1ms)").arg(end-start)
 | 
			
		||||
                                    << "with code" << m_exitCode
 | 
			
		||||
                                    << "IN" << p->workingDirectory();
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
                    qCritical() << "PROCESS" << m_command << "CRASHED with code"
 | 
			
		||||
                                << p->exitCode()
 | 
			
		||||
                                << QString("(after %1ms)").arg(end-start)
 | 
			
		||||
                                << "IN" << p->workingDirectory();
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
                qCritical() << "PROCESS" << m_command
 | 
			
		||||
                            << "DID NOT FINISH WITH" << wait
 | 
			
		||||
                            << "MS IN" << p->workingDirectory();
 | 
			
		||||
                            << "MS IN" << p->workingDirectory()
 | 
			
		||||
                            << QString("(runtime %1ms)").arg(end-start);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            qCritical() << "WRONG PROCESS STATE" << p->state()
 | 
			
		||||
                        << "IN" << p->workingDirectory();
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
			
		||||
        qCritical() << "PROCESS" << m_command << "TIMEOUT AT START"
 | 
			
		||||
                    << QString("(runtime %1ms)").arg(end-start)
 | 
			
		||||
                    << "IN" << p->workingDirectory();
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								update.cpp
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								update.cpp
									
									
									
									
									
								
							@@ -94,11 +94,11 @@ bool Update::unloadDCPlugin() {
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Update::Update(hwinf *hw,
 | 
			
		||||
               Worker *worker,
 | 
			
		||||
Update::Update(Worker *worker,
 | 
			
		||||
               QString customerRepository,
 | 
			
		||||
               QString customerNrStr,
 | 
			
		||||
               QString branchName,
 | 
			
		||||
               QString plugInDir,
 | 
			
		||||
               QString pluginName,
 | 
			
		||||
               QString workingDir,
 | 
			
		||||
               bool dryRun,
 | 
			
		||||
@@ -106,7 +106,7 @@ Update::Update(hwinf *hw,
 | 
			
		||||
               char const *serialInterface,
 | 
			
		||||
               char const *baudrate)
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
    , m_hw(hw)
 | 
			
		||||
    , m_hw(loadDCPlugin(QDir(plugInDir), pluginName))
 | 
			
		||||
    , m_worker(worker)
 | 
			
		||||
    , m_serialInterface(serialInterface)
 | 
			
		||||
    , m_baudrate(baudrate)
 | 
			
		||||
@@ -742,7 +742,17 @@ QStringList Update::getDcSoftAndHardWareVersion() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
			
		||||
    // always assume that serial line is open
 | 
			
		||||
    int tries = 20;
 | 
			
		||||
    while (!m_hw->sys_areDCdataValid()) { // 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";
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        m_hw->dc_autoRequest(true);
 | 
			
		||||
        QThread::msleep(500);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool res = false;
 | 
			
		||||
    QList<QString>::const_iterator it;
 | 
			
		||||
    for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
 | 
			
		||||
@@ -846,8 +856,8 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
			
		||||
            qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
 | 
			
		||||
            res = false;
 | 
			
		||||
        }
 | 
			
		||||
        m_worker->stopProgressLoop();
 | 
			
		||||
        m_worker->setProgress(100);
 | 
			
		||||
        // m_worker->stopProgressLoop();
 | 
			
		||||
        // m_worker->setProgress(100);
 | 
			
		||||
 | 
			
		||||
        if (res == false) {
 | 
			
		||||
            break;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								update.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								update.h
									
									
									
									
									
								
							@@ -21,8 +21,8 @@ class Worker;
 | 
			
		||||
class Update : public QObject {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    hwinf *m_hw;
 | 
			
		||||
    Worker *m_worker;
 | 
			
		||||
    hwinf *m_hw = nullptr;
 | 
			
		||||
    Worker *m_worker = nullptr;
 | 
			
		||||
    char const *m_serialInterface;
 | 
			
		||||
    char const *m_baudrate;
 | 
			
		||||
    QString m_customerRepository;
 | 
			
		||||
@@ -44,11 +44,11 @@ public:
 | 
			
		||||
    static QStringList split(QString line, QChar sep = ',');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    explicit Update(hwinf *hw,
 | 
			
		||||
                    Worker *worker,
 | 
			
		||||
    explicit Update(Worker *worker,
 | 
			
		||||
                    QString customerRepository,
 | 
			
		||||
                    QString customerNrStr,
 | 
			
		||||
                    QString branchName,
 | 
			
		||||
                    QString plugInDir,
 | 
			
		||||
                    QString pluginName,
 | 
			
		||||
                    QString workingDir,
 | 
			
		||||
                    bool dryRun = false,
 | 
			
		||||
@@ -58,6 +58,9 @@ public:
 | 
			
		||||
    virtual ~Update() override;
 | 
			
		||||
    bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
 | 
			
		||||
 | 
			
		||||
    hwinf *hw() { return m_hw; }
 | 
			
		||||
    hwinf const *hw() const { return m_hw; }
 | 
			
		||||
 | 
			
		||||
    //QString customerId() { return m_customerId; }
 | 
			
		||||
    //QString const customerId() const { return m_customerId; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								utils.cpp
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								utils.cpp
									
									
									
									
									
								
							@@ -46,23 +46,90 @@ QString Utils::zoneName(quint8 i) {
 | 
			
		||||
    return "N/A";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printCriticalErrorMsg(QString const &errorMsg) {
 | 
			
		||||
    qCritical() << QString(80, 'E');
 | 
			
		||||
void Utils::printCriticalErrorMsg(QString const &errorMsg, bool upper, bool lower) {
 | 
			
		||||
    if (upper) qCritical() << QString(80, 'E');
 | 
			
		||||
 | 
			
		||||
    qCritical() << errorMsg;
 | 
			
		||||
 | 
			
		||||
    if (lower) qCritical() << QString(80, 'E');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printCriticalErrorMsg(QStringList const &errorMsg) {
 | 
			
		||||
    qCritical() << QString(80, 'E');
 | 
			
		||||
    for (int i = 0; i < errorMsg.size(); ++i) {
 | 
			
		||||
        qCritical() << errorMsg.at(i);
 | 
			
		||||
    }
 | 
			
		||||
    qCritical() << QString(80, 'E');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printUpdateStatusMsg(QString const &updateMsg) {
 | 
			
		||||
    qCritical() << QString(80, 'U');
 | 
			
		||||
    qCritical() << updateMsg;
 | 
			
		||||
    qCritical() << QString(80, 'U');
 | 
			
		||||
void Utils::printUpdateStatusMsg(QDebug debug, QStringList const &updateMsg) {
 | 
			
		||||
    //if (updateMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'U');
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    Q_UNUSED(debug);
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < updateMsg.size(); ++i) {
 | 
			
		||||
        qInfo() << updateMsg.at(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //if (updateMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'U');
 | 
			
		||||
    //}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printInfoMsg(QString const &infoMsg) {
 | 
			
		||||
    qCritical() << QString(80, 'I');
 | 
			
		||||
    qCritical() << infoMsg;
 | 
			
		||||
    qCritical() << QString(80, 'I');
 | 
			
		||||
void Utils::printUpdateStatusMsg(QStringList const &updateMsg) {
 | 
			
		||||
    //if (updateMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'U');
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < updateMsg.size(); ++i) {
 | 
			
		||||
        qCritical() << updateMsg.at(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //if (updateMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'U');
 | 
			
		||||
    //}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printUpdateStatusMsg(QString const &updateMsg, bool upper, bool lower) {
 | 
			
		||||
    if (upper) qCritical() << QString(80, 'U');
 | 
			
		||||
 | 
			
		||||
    qCritical() << updateMsg;
 | 
			
		||||
 | 
			
		||||
    if (lower) qCritical() << QString(80, 'U');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printUpdateStatusMsg(QDebug debug, QString const &updateMsg,
 | 
			
		||||
                                 bool upper, bool lower) {
 | 
			
		||||
    if (upper) debug << QString(80, 'U');
 | 
			
		||||
 | 
			
		||||
    qInfo() << updateMsg;
 | 
			
		||||
 | 
			
		||||
    if (lower) debug << QString(80, 'U');
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printInfoMsg(QString const &infoMsg, bool upper, bool lower) {
 | 
			
		||||
    if (upper) qCritical() << QString(80, 'I');
 | 
			
		||||
 | 
			
		||||
    qCritical() << infoMsg;
 | 
			
		||||
 | 
			
		||||
    if (lower) qCritical() << QString(80, 'I');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printInfoMsg(QStringList const &infoMsg) {
 | 
			
		||||
    //if (infoMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'I');
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < infoMsg.size(); ++i) {
 | 
			
		||||
        qCritical() << infoMsg.at(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //if (infoMsg.size() > 1) {
 | 
			
		||||
    //    qCritical() << QString(80, 'I');
 | 
			
		||||
    //}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::printLineEditInfo(QStringList const &lines) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								utils.h
									
									
									
									
									
								
							@@ -8,13 +8,19 @@
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
namespace Utils {
 | 
			
		||||
    int read1stLineOfFile(QString fileName);
 | 
			
		||||
    QString zoneName(quint8 i);
 | 
			
		||||
    void printCriticalErrorMsg(QString const &errorMsg);
 | 
			
		||||
    void printInfoMsg(QString const &infoMsg);
 | 
			
		||||
    void printUpdateStatusMsg(QString const &updateMsg);
 | 
			
		||||
    void printCriticalErrorMsg(QString const &errorMsg, bool upper=false, bool lower=false);
 | 
			
		||||
    void printCriticalErrorMsg(QStringList const &errorMsg);
 | 
			
		||||
    void printInfoMsg(QString const &infoMsg, bool upper=false, bool lower=false);
 | 
			
		||||
    void printInfoMsg(QStringList const &infoMsg);
 | 
			
		||||
    void printUpdateStatusMsg(QDebug debug, QStringList const &updateMsg);
 | 
			
		||||
    void printUpdateStatusMsg(QStringList const &updateMsg);
 | 
			
		||||
    void printUpdateStatusMsg(QString const &updateMsg, bool upper=false, bool lower=false);
 | 
			
		||||
    void printUpdateStatusMsg(QDebug debug, QString const &updateMsg, bool upper=false, bool lower=false);
 | 
			
		||||
    void printLineEditInfo(QStringList const &lines);
 | 
			
		||||
    QString getTariffLoadTime(QString fileName);
 | 
			
		||||
    QString rstrip(QString const &str);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1435
									
								
								worker.cpp
									
									
									
									
									
								
							
							
						
						
									
										1435
									
								
								worker.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user