Compare commits
	
		
			212 Commits
		
	
	
		
			v1.1.1
			...
			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 | |||
| 9b175d7789 | |||
| 2d7f145a25 | |||
| 4589c4ca76 | |||
| a32258a59e | |||
| 22f25e5251 | |||
| 258d883a51 | |||
| 504e242d42 | |||
| 731cdcbe09 | |||
| b4e2d4c54a | |||
| 42961dea40 | |||
| fd2f601f67 | |||
| b45af505cd | |||
| 2dfe80b654 | |||
| 4b9dcc5e99 | |||
| 53639b55c9 | |||
| 3a83efbd3f | |||
| c9d6a8d245 | |||
| 91db59b9f3 | |||
| 1d81e6b650 | |||
| 6d57b45d1a | |||
| 4e7ce2cd70 | |||
| 47fac31223 | |||
| 0d353cfbcf | |||
| bdcb073bf8 | |||
| 226553a8ab | |||
| d4ee56559b | |||
| 355b28ba40 | |||
| edeff35d7e | |||
| 09d5de1b0b | |||
| 145fdab26e | |||
| 89d1ec5b21 | |||
| f38c975dc6 | |||
| fba007aa35 | |||
| 8b6adb3ea7 | |||
| 30603317c6 | |||
| 7083f3b4f8 | |||
| 7ff866525e | |||
| 2164037123 | |||
| 2e7d33c4c8 | |||
| 2a2751f6f3 | |||
| 2764ef4371 | |||
| 9783f343e1 | |||
| 8c6f0dfcc7 | |||
| d688ad3d5c | |||
| 7b3f652b0e | |||
| 4cc42b2a65 | |||
| d783fd7fb6 | |||
| e0a0ff54e1 | |||
| 863d052a21 | |||
| 61b3d29e31 | |||
| cac4f7249e | |||
| 3223c430be | |||
| c09682ea33 | |||
| fef1d43d5f | |||
| 705424727b | |||
| b96f0896e3 | |||
| a3967c76ac | |||
| 
						
						
							
						
						1197598a3d
	
				 | 
					
					
						|||
| 
						
						
							
						
						ec13e97226
	
				 | 
					
					
						|||
| 
						
						
							
						
						a8dd9d7e24
	
				 | 
					
					
						|||
| 82751eb1d4 | |||
| 17a4a69df2 | |||
| a03261d04a | |||
| 7832ef5d8c | |||
| 9c213d0a97 | |||
| 18378afdc5 | |||
| 6dd8a8c6b3 | |||
| adfb358e12 | |||
| ff418b11a1 | |||
| 38e79f0354 | |||
| 103b3f3f9c | |||
| ff6a6e0e45 | |||
| afbce3b4ea | |||
| 823e59a582 | |||
| 01cfbddfb1 | |||
| 838efd3945 | |||
| 9a65cb4456 | |||
| df0951d671 | |||
| 60cc752819 | |||
| 57b4716e2a | |||
| 15f28e9ffd | |||
| a07893ddab | |||
| d0eb1d12d8 | |||
| cd59a39569 | |||
| 67c8b2f472 | |||
| 5158878ce2 | |||
| b6971c1db5 | |||
| 9df46a1c49 | |||
| 6765b12f0c | |||
| 3e925756cf | |||
| b2798b349e | |||
| 64dce44fe1 | |||
| 7e96b65c1b | |||
| 276d65a9d8 | |||
| ba71728979 | |||
| e82742a609 | |||
| 6773a7243a | |||
| 22c8997f1e | |||
| 9531a08b4a | |||
| c065b57f0c | |||
| cef05b7511 | |||
| bb35e985ad | |||
| 981a2ea13a | |||
| b14b296011 | |||
| 1ef9853876 | |||
| 01d8312aa8 | |||
| 507586f9dc | |||
| 12ffa71455 | |||
| a84f495d43 | |||
| 7e4b5006eb | |||
| 0a28f0d82c | |||
| 5427844977 | |||
| a45e552d90 | |||
| be28570d23 | |||
| 1509e8619c | |||
| a8df026a80 | |||
| a803907449 | |||
| afd31f1b27 | |||
| f8fef38009 | |||
| cbe1fd387d | |||
| 1620b73d01 | |||
| 4ebdcf56a0 | |||
| 99b9419150 | |||
| 4307fb96a6 | |||
| c35390b6d6 | |||
| fff6bd2b49 | |||
| 631ade1954 | |||
| 337bdd1bb0 | |||
| 978cc16304 | |||
| bea8242d6f | |||
| 56daa84a14 | |||
| 17ddfd0ddd | |||
| 2ac8c4cfc6 | |||
| 0559ff64e2 | |||
| 385a7b7b00 | |||
| 503b7c64f9 | |||
| beec9c2f9d | |||
| 5263b7de0f | |||
| 9b4d0494c8 | |||
| 0f2ee0349f | |||
| e700a40875 | |||
| 1eba5338e4 | |||
| f20be9ddcf | |||
| 7631c05e22 | |||
| ad93e536f0 | |||
| 259da8200e | |||
| 8d528f0f55 | |||
| 66d0214720 | |||
| 86064979b4 | |||
| 86c996d7ac | 
@@ -15,47 +15,111 @@ 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.0.0
 | 
					
 | 
				
			||||||
 | 
					# 1.3.6 :   Do not update device-controller/json files, but have the library
 | 
				
			||||||
 | 
					#           (in a later step) do that.
 | 
				
			||||||
 | 
					#           Fixed sending messages to ISMAS.
 | 
				
			||||||
 | 
					#           Always execute contents of opkg_commands-file (even if there are no
 | 
				
			||||||
 | 
					#           changes).
 | 
				
			||||||
 | 
					# 1.3.7 :   Wait forever for git-commands to finish in QProcess executing such
 | 
				
			||||||
 | 
					#           a command.
 | 
				
			||||||
 | 
					# 1.3.8 :   Remove accessing opkg_commands under file-system-path /etc/psa_update.
 | 
				
			||||||
 | 
					#           Activate download of json-configuration files.
 | 
				
			||||||
 | 
					# 1.3.9 :   Fix sendLastVersion: use configured branch and not master branch in
 | 
				
			||||||
 | 
					#               git show origin/master -s --format="c=%h m=%s d=%cI"    ==>
 | 
				
			||||||
 | 
					#               git show origin/zg1/zone1 -s --format="c=%h m=%s d=%cI"
 | 
				
			||||||
 | 
					#           Use dynamic values for os-release and apism-version when sending
 | 
				
			||||||
 | 
					#           last version info.
 | 
				
			||||||
 | 
					# 1.3.10:   Fix premature killing opkg-commands: detected timeout of 100s was
 | 
				
			||||||
 | 
					#           too small when updating apism.
 | 
				
			||||||
 | 
					#           Fix display of UPDATE_SUCCESS when opkg_command fails. Detected when
 | 
				
			||||||
 | 
					#           updating apsim failed.
 | 
				
			||||||
 | 
					# 1.3.11:   Integrate version of ATBUpdateTool in SendLastVersion-ISMAS-message.
 | 
				
			||||||
 | 
					# 1.3.12:   Add command parameters for output of yocto-infos about ATBUpdateTool.
 | 
				
			||||||
 | 
					#           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")
 | 
				
			||||||
 | 
					    BUILD_TIME=$$system("time /t")
 | 
				
			||||||
 | 
					} else {
 | 
				
			||||||
 | 
					    BUILD_DATE=$$system("date +%d-%m-%y")
 | 
				
			||||||
 | 
					    BUILD_TIME=$$system("date +%H:%M:%S")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INCLUDEPATH += plugins
 | 
					INCLUDEPATH += plugins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CONFIG += c++17 console
 | 
					CONFIG += c++17
 | 
				
			||||||
# CONFIG -= app_bundle
 | 
					# CONFIG -= app_bundle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
 | 
					DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
 | 
				
			||||||
 | 
					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 += -g
 | 
				
			||||||
QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
					QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# custom target for 'git subtree'
 | 
					 | 
				
			||||||
# subtree.target = subtree
 | 
					 | 
				
			||||||
# subtree.commands = git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
 | 
					 | 
				
			||||||
# subtree.depends =
 | 
					 | 
				
			||||||
# QMAKE_EXTRA_UNIX_TARGETS += subtree
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# ! exists(DCPlugin) {
 | 
					 | 
				
			||||||
#     $$system("git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash")
 | 
					 | 
				
			||||||
# } else {
 | 
					 | 
				
			||||||
    # $$system("git subtree pull --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash")
 | 
					 | 
				
			||||||
# }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# You can make your code fail to compile if it uses deprecated APIs.
 | 
					 | 
				
			||||||
# In order to do so, uncomment the following line.
 | 
					 | 
				
			||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
contains( CONFIG, PTU5 ) {
 | 
					contains( CONFIG, PTU5 ) {
 | 
				
			||||||
    greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
 | 
					    greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
 | 
				
			||||||
    CONFIG += link_pkgconfig
 | 
					    CONFIG += link_pkgconfig
 | 
				
			||||||
    lessThan(QT_MAJOR_VERSION, 5):   PKGCONFIG += qextserialport
 | 
					    lessThan(QT_MAJOR_VERSION, 5):   PKGCONFIG += qextserialport
 | 
				
			||||||
    QMAKE_CXXFLAGS += -std=c++17   # for GCC >= 4.7
 | 
					    QMAKE_CXXFLAGS += -O2 -std=c++17   # for GCC >= 4.7
 | 
				
			||||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
					    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
				
			||||||
    ARCH = PTU5
 | 
					    ARCH = PTU5
 | 
				
			||||||
    DEFINES+=PTU5
 | 
					    DEFINES+=PTU5
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
contains( CONFIG, PTU5_YOCTO ) {
 | 
					contains( CONFIG, PTU5_YOCTO ) {
 | 
				
			||||||
    greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
 | 
					    greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
 | 
				
			||||||
    QMAKE_CXXFLAGS += -std=c++17   # for GCC >= 4.7
 | 
					    QMAKE_CXXFLAGS += -std=c++17   # for GCC >= 4.7
 | 
				
			||||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
					    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
				
			||||||
    PTU5BASEPATH = /opt/devel/ptu5
 | 
					    PTU5BASEPATH = /opt/devel/ptu5
 | 
				
			||||||
    ARCH = PTU5
 | 
					    ARCH = PTU5
 | 
				
			||||||
    DEFINES+=PTU5
 | 
					    DEFINES+=PTU5
 | 
				
			||||||
@@ -69,7 +133,7 @@ contains( CONFIG, DesktopLinux ) {
 | 
				
			|||||||
    # QMAKE_CC = ccache $$QMAKE_CC
 | 
					    # QMAKE_CC = ccache $$QMAKE_CC
 | 
				
			||||||
    # QMAKE_CXX = ccache $$QMAKE_CXX
 | 
					    # QMAKE_CXX = ccache $$QMAKE_CXX
 | 
				
			||||||
    QMAKE_CXXFLAGS += -std=c++17
 | 
					    QMAKE_CXXFLAGS += -std=c++17
 | 
				
			||||||
    QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
					    # QMAKE_CXXFLAGS += -Wno-deprecated-copy
 | 
				
			||||||
    linux-clang {  QMAKE_CXXFLAGS += -Qunused-arguments   }
 | 
					    linux-clang {  QMAKE_CXXFLAGS += -Qunused-arguments   }
 | 
				
			||||||
    ARCH = DesktopLinux
 | 
					    ARCH = DesktopLinux
 | 
				
			||||||
    DEFINES+=DesktopLinux
 | 
					    DEFINES+=DesktopLinux
 | 
				
			||||||
@@ -78,6 +142,7 @@ contains( CONFIG, DesktopLinux ) {
 | 
				
			|||||||
SOURCES += \
 | 
					SOURCES += \
 | 
				
			||||||
        main.cpp \
 | 
					        main.cpp \
 | 
				
			||||||
        progress_event.cpp \
 | 
					        progress_event.cpp \
 | 
				
			||||||
 | 
					        update_dc_event.cpp \
 | 
				
			||||||
        mainwindow.cpp \
 | 
					        mainwindow.cpp \
 | 
				
			||||||
        utils.cpp \
 | 
					        utils.cpp \
 | 
				
			||||||
        update.cpp \
 | 
					        update.cpp \
 | 
				
			||||||
@@ -85,12 +150,12 @@ SOURCES += \
 | 
				
			|||||||
        ismas/ismas_client.cpp \
 | 
					        ismas/ismas_client.cpp \
 | 
				
			||||||
        process/command.cpp \
 | 
					        process/command.cpp \
 | 
				
			||||||
        message_handler.cpp \
 | 
					        message_handler.cpp \
 | 
				
			||||||
        worker.cpp \
 | 
					        worker.cpp
 | 
				
			||||||
        worker_thread.cpp
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
HEADERS += \
 | 
					HEADERS += \
 | 
				
			||||||
        update.h \
 | 
					        update.h \
 | 
				
			||||||
        progress_event.h \
 | 
					        progress_event.h \
 | 
				
			||||||
 | 
					        update_dc_event.h \
 | 
				
			||||||
        utils.h \
 | 
					        utils.h \
 | 
				
			||||||
        mainwindow.h \
 | 
					        mainwindow.h \
 | 
				
			||||||
        git/git_client.h \
 | 
					        git/git_client.h \
 | 
				
			||||||
@@ -99,24 +164,11 @@ HEADERS += \
 | 
				
			|||||||
        process/command.h \
 | 
					        process/command.h \
 | 
				
			||||||
        message_handler.h \
 | 
					        message_handler.h \
 | 
				
			||||||
        worker.h \
 | 
					        worker.h \
 | 
				
			||||||
        worker_thread.h \
 | 
					 | 
				
			||||||
        plugins/interfaces.h
 | 
					        plugins/interfaces.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FORMS += \
 | 
					FORMS += \
 | 
				
			||||||
    mainwindow.ui
 | 
					    mainwindow.ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OTHER_FILES += \
 | 
					 | 
				
			||||||
    /opt/app/tools/atbupdate/update_log.csv \
 | 
					 | 
				
			||||||
    main.cpp.bck \
 | 
					 | 
				
			||||||
    main.cpp.bck2 \
 | 
					 | 
				
			||||||
    main.cpp.bck3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# https://blog.developer.atlassian.com/the-power-of-git-subtree/?_ga=2-71978451-1385799339-1568044055-1068396449-1567112770
 | 
					 | 
				
			||||||
# git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
 | 
					 | 
				
			||||||
# git subtree pull --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
 | 
					 | 
				
			||||||
# include(./DCPlugin/DCPlugin.pri)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
##########################################################################################
 | 
					##########################################################################################
 | 
				
			||||||
# for running program on target through QtCreator
 | 
					# for running program on target through QtCreator
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,29 +26,93 @@ GitClient::GitClient(QString const &customerNrStr,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool GitClient::gitCloneCustomerRepository() {
 | 
					bool GitClient::gitCloneCustomerRepository() {
 | 
				
			||||||
    QString gitCommand("git clone ");
 | 
					    /*  Blobless clone
 | 
				
			||||||
 | 
					        ==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        When using the --filter=blob:none option, the initial git clone will
 | 
				
			||||||
 | 
					        download all reachable commits and trees, and only download the blobs
 | 
				
			||||||
 | 
					        for commits when you do a git checkout. This includes the first checkout
 | 
				
			||||||
 | 
					        inside the git clone operation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The important thing to notice is that we have a copy of every blob at
 | 
				
			||||||
 | 
					        HEAD but the blobs in the history are not present. If your repository
 | 
				
			||||||
 | 
					        has a deep history full of large blobs, then this option can
 | 
				
			||||||
 | 
					        significantly reduce your git clone times. The commit and tree data is
 | 
				
			||||||
 | 
					        still present, so any subsequent git checkout only needs to download
 | 
				
			||||||
 | 
					        the missing blobs. The Git client knows how to batch these requests to
 | 
				
			||||||
 | 
					        ask the server only for the missing blobs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Further, when running git fetch in a blobless clone, the server only
 | 
				
			||||||
 | 
					        sends the new commits and trees. The new blobs are downloaded only
 | 
				
			||||||
 | 
					        after a git checkout. Note that git pull runs git fetch and then git
 | 
				
			||||||
 | 
					        merge, so it will download the necessary blobs during the git merge
 | 
				
			||||||
 | 
					        command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        When using a blobless clone, you will trigger a blob download whenever
 | 
				
			||||||
 | 
					        you need the contents of a file, but you will not need one if you only
 | 
				
			||||||
 | 
					        need the OID (object-id) of a file. This means that git log can detect
 | 
				
			||||||
 | 
					        which commits changed a given path without needing to download extra
 | 
				
			||||||
 | 
					        data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        This means that blobless clones can perform commands like git
 | 
				
			||||||
 | 
					        merge-base, git log, or even git log -- <path> with the same performance
 | 
				
			||||||
 | 
					        as a full clone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Commands like git diff or git blame <path> require the contents of the
 | 
				
			||||||
 | 
					        paths to compute diffs, so these will trigger blob downloads the first
 | 
				
			||||||
 | 
					        time they are run. However, the good news is that after that you will
 | 
				
			||||||
 | 
					        have those blobs in your repository and do not need to download them a
 | 
				
			||||||
 | 
					        second time. Most developers only need to run git blame on a small
 | 
				
			||||||
 | 
					        number of files, so this tradeoff of a slightly slower git blame command
 | 
				
			||||||
 | 
					        is worth the faster clone and fetch times.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Note: git v2.18 does not support treeless clones: --filter=tree:0.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 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;
 | 
					    gitCommand += m_repositoryPath;
 | 
				
			||||||
    Command c(gitCommand);
 | 
					    Command c(gitCommand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qInfo() << "IN CURRENT WD" << m_workingDirectory
 | 
					    qInfo() << "IN CURRENT WD" << m_workingDirectory
 | 
				
			||||||
            << "CLONE" << m_repositoryPath << "...";
 | 
					            << "CLONE VIA COMMAND" << gitCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (c.execute(m_workingDirectory)) { // execute the command in wd
 | 
					    if (c.execute(m_workingDirectory)) { // execute the command in wd
 | 
				
			||||||
        QString const result = c.getCommandResult();
 | 
					        QString const result = c.getCommandResult();
 | 
				
			||||||
        if (!result.isEmpty()) {
 | 
					        if (!result.isEmpty()) {
 | 
				
			||||||
            // Cloning into 'customer_281'...\n
 | 
					            // Cloning into 'customer_281'...\n
 | 
				
			||||||
            static QRegularExpression re("(^\\s*Cloning\\s+into\\s+[']\\s*)(.*)(\\s*['].*$)");
 | 
					            int customer = -1;
 | 
				
			||||||
            QRegularExpressionMatch match = re.match(result);
 | 
					            int cloning = result.indexOf("Cloning", 0, Qt::CaseInsensitive);
 | 
				
			||||||
            if (match.hasMatch()) {
 | 
					            if (cloning != -1) {
 | 
				
			||||||
                if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
					                customer = result.indexOf("customer_", cloning, Qt::CaseInsensitive);
 | 
				
			||||||
                    if (match.captured(2).trimmed() == m_customerNr) {
 | 
					                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";
 | 
					                            qInfo() << "CLONING" << m_repositoryPath << "OK";
 | 
				
			||||||
                            return true;
 | 
					                            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. CLONE_RESULT=") + result);
 | 
					            Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					                QString("ERROR CLONE RESULT HAS WRONG FORMAT. CLONING=%1 CUSTOMER=%2 CLONE_RESULT=%3")
 | 
				
			||||||
 | 
					                    .arg(cloning)
 | 
				
			||||||
 | 
					                    .arg(customer)
 | 
				
			||||||
 | 
					                    .arg(result));
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Utils::printCriticalErrorMsg("ERROR CLONE RESULT IS EMPTY");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -114,6 +178,53 @@ bool GitClient::gitCloneAndCheckoutBranch() {
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QStringList GitClient::gitShowReason(QString branchName) {
 | 
				
			||||||
 | 
					    QStringList lst;
 | 
				
			||||||
 | 
					    if (QDir(m_customerRepository).exists()) {
 | 
				
			||||||
 | 
					        // %h: commit (short form)
 | 
				
			||||||
 | 
					        // %s: commit message
 | 
				
			||||||
 | 
					        // %cI: commit date, strict ISO 8601 format
 | 
				
			||||||
 | 
					        // Note: branch with branchName has to exist: format zg1/zone1
 | 
				
			||||||
 | 
					        Command c(QString("git show origin/%1 -s --format=\"c=%h m=%s d=%cI\"").arg(branchName));
 | 
				
			||||||
 | 
					        if (c.execute(m_customerRepository)) {
 | 
				
			||||||
 | 
					            QString const s = c.getCommandResult().trimmed();
 | 
				
			||||||
 | 
					            int const c = s.indexOf("c=");
 | 
				
			||||||
 | 
					            int const m = s.indexOf("m=");
 | 
				
			||||||
 | 
					            int const d = s.indexOf("d=");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            QString msg = IsmasClient::getReasonForLastSendVersion();
 | 
				
			||||||
 | 
					            QString commit{""}, date{""};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (c != -1) {
 | 
				
			||||||
 | 
					                int start = c + 2;
 | 
				
			||||||
 | 
					                if (m >= start) {
 | 
				
			||||||
 | 
					                    int length = m - start;
 | 
				
			||||||
 | 
					                    commit = s.mid(start, length).trimmed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    start = m + 2;
 | 
				
			||||||
 | 
					                    if (d >= start) {
 | 
				
			||||||
 | 
					                        length = d - start;
 | 
				
			||||||
 | 
					                        msg += " (";
 | 
				
			||||||
 | 
					                        msg = s.mid(start, length).trimmed();
 | 
				
			||||||
 | 
					                        msg += ")";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        start = d + 2;
 | 
				
			||||||
 | 
					                        date = s.mid(start);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!commit.isEmpty() && !msg.isEmpty() && !date.isEmpty()) {
 | 
				
			||||||
 | 
					                    lst << commit << msg << date;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        qCritical() << "CUSTOMER_REPOSITORY" << m_customerRepository
 | 
				
			||||||
 | 
					                    << "DOES NOT EXIST";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return lst;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 Zu beachten: wird eine datei neu hinzugefuegt (git add/commit) dann aber gleich
 | 
					 Zu beachten: wird eine datei neu hinzugefuegt (git add/commit) dann aber gleich
 | 
				
			||||||
 wieder geloscht, so wird sie im diff nicht angezeigt.
 | 
					 wieder geloscht, so wird sie im diff nicht angezeigt.
 | 
				
			||||||
@@ -168,19 +279,34 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
 | 
				
			|||||||
    return std::nullopt;
 | 
					    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
 | 
					 Hat sich nichts geaendert, so werden auch keine Commits <>..<> angezeigt
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
std::optional<QString> GitClient::gitFetch() {
 | 
					std::optional<QString> GitClient::gitPull() {
 | 
				
			||||||
    if (QDir(m_customerRepository).exists()) {
 | 
					    if (QDir(m_customerRepository).exists()) {
 | 
				
			||||||
        qInfo() << "BRANCH NAME" << m_branchName;
 | 
					        qInfo() << "BRANCH NAME" << m_branchName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Command c("git fetch");
 | 
					        Command c("git pull");
 | 
				
			||||||
        if (c.execute(m_customerRepository)) {
 | 
					        if (c.execute(m_customerRepository)) {
 | 
				
			||||||
            QString const s = c.getCommandResult().trimmed();
 | 
					            QString const s = c.getCommandResult().trimmed();
 | 
				
			||||||
            if (!s.isEmpty()) {
 | 
					            if (!s.isEmpty()) {
 | 
				
			||||||
                QStringList lines = Update::split(s, '\n');
 | 
					                QStringList lines = Update::split(s, '\n');
 | 
				
			||||||
 | 
					                worker()->CONSOLE(lines) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
 | 
				
			||||||
                if (!lines.empty()) {
 | 
					                if (!lines.empty()) {
 | 
				
			||||||
 | 
					                    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");
 | 
					                        int zoneNr = Utils::read1stLineOfFile("/mnt/system_data/zone_nr");
 | 
				
			||||||
                        m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
 | 
					                        m_branchName = (zoneNr != 0) ? QString("zg1/zone%1").arg(zoneNr) : "master";
 | 
				
			||||||
                        // lines can look like this:
 | 
					                        // lines can look like this:
 | 
				
			||||||
@@ -199,61 +325,42 @@ std::optional<QString> GitClient::gitFetch() {
 | 
				
			|||||||
                                QRegularExpressionMatch match = re.match(lines.at(i));
 | 
					                                QRegularExpressionMatch match = re.match(lines.at(i));
 | 
				
			||||||
                                if (match.hasMatch()) {
 | 
					                                if (match.hasMatch()) {
 | 
				
			||||||
                                    if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
					                                    if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches
 | 
				
			||||||
                                    return match.captured(2);
 | 
					                                        QString const matchCaptured = match.captured(2);
 | 
				
			||||||
 | 
					                                        worker()->CONSOLE(QStringList(matchCaptured)) << Worker::UPDATE_STEP::UPDATE_REPOSITORY;
 | 
				
			||||||
 | 
					                                        return matchCaptured;
 | 
				
			||||||
                                    } else {
 | 
					                                    } else {
 | 
				
			||||||
                                    emit m_worker->showErrorMessage("git fetch",
 | 
					                                        QStringList lst(QString("(wrong capture count (%1)").arg(re.captureCount()));
 | 
				
			||||||
                                        QString("(wrong cap-count (%1)").arg(re.captureCount()));
 | 
					                                        worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                } else {
 | 
					                                } else {
 | 
				
			||||||
                                emit m_worker->showErrorMessage("git fetch",
 | 
					                                    QStringList lst("no regex-match for commits");
 | 
				
			||||||
                                    "no regex-match for commits");
 | 
					                                    worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
                                Utils::printCriticalErrorMsg("NO REGEX MATCH FOR COMMITS");
 | 
					 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        if (!found) {
 | 
					                        if (!found) {
 | 
				
			||||||
                        emit m_worker->showErrorMessage("git fetch",
 | 
					                            QStringList lst(QString("unknown branch name ") + m_branchName);
 | 
				
			||||||
                            QString("unkown branch name ") + m_branchName);
 | 
					                            worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
                        Utils::printCriticalErrorMsg("UNKNOWN BRANCH NAME " + m_branchName);
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                    emit m_worker->showErrorMessage("git fetch",
 | 
					                        return "Already up to date";
 | 
				
			||||||
                        QString("wrong format for result of 'git fetch' ") + s);
 | 
					 | 
				
			||||||
                    Utils::printCriticalErrorMsg(QString("WRONG FORMAT FOR RESULT OF 'GIT FETCH' ") + s);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                emit m_worker->showErrorMessage("git fetch", "empty result for 'git fetch'");
 | 
					                    QStringList lst(QString("WRONG FORMAT FOR RESULT OF 'GIT PULL' ") + s);
 | 
				
			||||||
                Utils::printCriticalErrorMsg("EMPTY RESULT FOR 'GIT FETCH'");
 | 
					                    worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                QStringList lst("EMPTY RESULT FOR 'GIT PULL'");
 | 
				
			||||||
 | 
					                worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        emit m_worker->showErrorMessage("git fetch", QString("repository ") + m_customerRepository + " does not exist");
 | 
					        QStringList lst(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
 | 
				
			||||||
        Utils::printCriticalErrorMsg(QString("REPOSITORY ") + m_customerRepository + " DOES NOT EXIST");
 | 
					        worker()->GUI(lst) << (worker()->CONSOLE(lst) << Worker::UPDATE_STEP::UPDATE_REPOSITORY_FAILURE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return std::nullopt;
 | 
					    return std::nullopt;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool GitClient::gitFetchAndDiff() {
 | 
					 | 
				
			||||||
    if (gitFetch()) {
 | 
					 | 
				
			||||||
        QString gitCommand("git diff --compact-summary HEAD..FETCH_HEAD");
 | 
					 | 
				
			||||||
        Command c(gitCommand);
 | 
					 | 
				
			||||||
        return c.execute(m_workingDirectory);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool GitClient::gitPull() {
 | 
					 | 
				
			||||||
    if (QDir(m_customerRepository).exists()) {
 | 
					 | 
				
			||||||
        Command c("git pull");
 | 
					 | 
				
			||||||
        if (c.execute(m_customerRepository)) {
 | 
					 | 
				
			||||||
            qInfo() << "PULLED INTO" << m_customerRepository;
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Utils::printCriticalErrorMsg(QString("PULL INTO " + m_customerRepository + " FAILED"));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::optional<QStringList> GitClient::gitMerge() {
 | 
					std::optional<QStringList> GitClient::gitMerge() {
 | 
				
			||||||
    Command c("git merge");
 | 
					    Command c("git merge");
 | 
				
			||||||
    if (c.execute(m_workingDirectory)) {
 | 
					    if (c.execute(m_workingDirectory)) {
 | 
				
			||||||
@@ -289,7 +396,7 @@ QString GitClient::gitBlob(QString fileName) {
 | 
				
			|||||||
    if (fi.exists()) {
 | 
					    if (fi.exists()) {
 | 
				
			||||||
        QString const gitCommand = QString("git hash-object %1").arg(fileName);
 | 
					        QString const gitCommand = QString("git hash-object %1").arg(fileName);
 | 
				
			||||||
        Command c(gitCommand);
 | 
					        Command c(gitCommand);
 | 
				
			||||||
        if (c.execute(m_workingDirectory)) {
 | 
					        if (c.execute("/tmp")) {
 | 
				
			||||||
            return c.getCommandResult().trimmed();
 | 
					            return c.getCommandResult().trimmed();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,14 +43,18 @@ class GitClient : public QObject {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool gitCloneAndCheckoutBranch();
 | 
					    bool gitCloneAndCheckoutBranch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::optional<QString> gitFetch();
 | 
					    Worker *worker() { return m_worker; }
 | 
				
			||||||
    bool gitFetchAndDiff();
 | 
					    Worker const *worker() const { return m_worker; }
 | 
				
			||||||
    bool gitPull();
 | 
					
 | 
				
			||||||
 | 
					    std::optional<QString> gitPull();
 | 
				
			||||||
    std::optional<QStringList> gitDiff(QString const &commit);
 | 
					    std::optional<QStringList> gitDiff(QString const &commit);
 | 
				
			||||||
    std::optional<QStringList> gitMerge();
 | 
					    std::optional<QStringList> gitMerge();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool gitFsck();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString gitLastCommit(QString fileName);
 | 
					    QString gitLastCommit(QString fileName);
 | 
				
			||||||
    QString gitBlob(QString fileName);
 | 
					    QStringList gitShowReason(QString branchName);
 | 
				
			||||||
 | 
					    static QString gitBlob(QString fileName);
 | 
				
			||||||
    QString gitCommitForBlob(QString blob);
 | 
					    QString gitCommitForBlob(QString blob);
 | 
				
			||||||
    bool gitIsFileTracked(QString file2name);
 | 
					    bool gitIsFileTracked(QString file2name);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
#include "ismas/ismas_client.h"
 | 
					#include "ismas/ismas_client.h"
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <cstdio>
 | 
					#include <cstdio>
 | 
				
			||||||
@@ -22,6 +23,15 @@
 | 
				
			|||||||
#include <QJsonObject>
 | 
					#include <QJsonObject>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
 | 
					########################
 | 
				
			||||||
 | 
					# Spec vom 27.10.2023:
 | 
				
			||||||
 | 
					# U0010 -> %-Werte
 | 
				
			||||||
 | 
					# U0001 -> 100%
 | 
				
			||||||
 | 
					# U0003 -> "FAIL"
 | 
				
			||||||
 | 
					# U0002 -> "" (OK -> WAIT state reset)
 | 
				
			||||||
 | 
					# ISMAS -> "WAIT"
 | 
				
			||||||
 | 
					########################
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
# $1: EVENT: U0001 update finished: 100%
 | 
					# $1: EVENT: U0001 update finished: 100%
 | 
				
			||||||
#            U0002 reset TRG
 | 
					#            U0002 reset TRG
 | 
				
			||||||
#            U0003 error
 | 
					#            U0003 error
 | 
				
			||||||
@@ -46,6 +56,12 @@ void IsmasClient::printDebugMessage(int port,
 | 
				
			|||||||
                                    QString const &clientIP,
 | 
					                                    QString const &clientIP,
 | 
				
			||||||
                                    int clientPort,
 | 
					                                    int clientPort,
 | 
				
			||||||
                                    QString const &message) {
 | 
					                                    QString const &message) {
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					    Q_UNUSED(port);
 | 
				
			||||||
 | 
					    Q_UNUSED(clientIP);
 | 
				
			||||||
 | 
					    Q_UNUSED(clientPort);
 | 
				
			||||||
 | 
					    Q_UNUSED(message);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    qDebug().noquote()
 | 
					    qDebug().noquote()
 | 
				
			||||||
        << "\n"
 | 
					        << "\n"
 | 
				
			||||||
        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
					        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
				
			||||||
@@ -54,12 +70,19 @@ void IsmasClient::printDebugMessage(int port,
 | 
				
			|||||||
        << "local address ..." << clientIP << "\n"
 | 
					        << "local address ..." << clientIP << "\n"
 | 
				
			||||||
        << "local port ......" << clientPort << "\n"
 | 
					        << "local port ......" << clientPort << "\n"
 | 
				
			||||||
        << message;
 | 
					        << message;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IsmasClient::printInfoMessage(int port,
 | 
					void IsmasClient::printInfoMessage(int port,
 | 
				
			||||||
                                   QString const &clientIP,
 | 
					                                   QString const &clientIP,
 | 
				
			||||||
                                   int clientPort,
 | 
					                                   int clientPort,
 | 
				
			||||||
                                   QString const &message) {
 | 
					                                   QString const &message) {
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					    Q_UNUSED(port);
 | 
				
			||||||
 | 
					    Q_UNUSED(clientIP);
 | 
				
			||||||
 | 
					    Q_UNUSED(clientPort);
 | 
				
			||||||
 | 
					    Q_UNUSED(message);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    qInfo().noquote()
 | 
					    qInfo().noquote()
 | 
				
			||||||
        << "\n"
 | 
					        << "\n"
 | 
				
			||||||
        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
					        << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
 | 
				
			||||||
@@ -68,6 +91,7 @@ void IsmasClient::printInfoMessage(int port,
 | 
				
			|||||||
        << "local address ..." << clientIP << "\n"
 | 
					        << "local address ..." << clientIP << "\n"
 | 
				
			||||||
        << "local port ......" << clientPort << "\n"
 | 
					        << "local port ......" << clientPort << "\n"
 | 
				
			||||||
        << message;
 | 
					        << message;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IsmasClient::printErrorMessage(int port,
 | 
					void IsmasClient::printErrorMessage(int port,
 | 
				
			||||||
@@ -137,7 +161,12 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
    so_linger.l_onoff = 1;
 | 
					    so_linger.l_onoff = 1;
 | 
				
			||||||
    so_linger.l_linger = 0;
 | 
					    so_linger.l_linger = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int maxfdp1;
 | 
				
			||||||
 | 
					    fd_set rset;
 | 
				
			||||||
 | 
					    fd_set wset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
 | 
					    setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
 | 
				
			||||||
 | 
					    // no reliable, but does not harm, as we use select() as well
 | 
				
			||||||
    setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
 | 
					    setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
 | 
				
			||||||
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
 | 
					    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
 | 
				
			||||||
    int flag = 1;
 | 
					    int flag = 1;
 | 
				
			||||||
@@ -151,6 +180,37 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
    int loop = 0;
 | 
					    int loop = 0;
 | 
				
			||||||
    int bytesWritten = 0;
 | 
					    int bytesWritten = 0;
 | 
				
			||||||
    while (bytesWritten < bytesToWrite) {
 | 
					    while (bytesWritten < bytesToWrite) {
 | 
				
			||||||
 | 
					        errno = 0;
 | 
				
			||||||
 | 
					        FD_ZERO(&wset);
 | 
				
			||||||
 | 
					        FD_SET(sockfd, &wset);
 | 
				
			||||||
 | 
					        maxfdp1 = sockfd + 1;
 | 
				
			||||||
 | 
					        tv.tv_sec = 60;  /* 60 secs timeout for read and write -> APISM cuts the connection after 30s */
 | 
				
			||||||
 | 
					        tv.tv_usec = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int const w = select(maxfdp1, NULL, &wset, NULL, &tv);
 | 
				
			||||||
 | 
					        if (w < 0) { // error
 | 
				
			||||||
 | 
					            if (errno == EINTR) {
 | 
				
			||||||
 | 
					                printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                    QString("INTERRUPTED BY SIGNAL (1) (") + strerror(errno) + ")");
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                        QString("SELECT-ERROR (WRITE) %1(").arg(loop) + strerror(errno) + ")");
 | 
				
			||||||
 | 
					                ::close(sockfd);
 | 
				
			||||||
 | 
					                return std::nullopt;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (w == 0) { // timeout
 | 
				
			||||||
 | 
					            printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                    QString("SELECT-TIMEOUT (WRITE) %1(").arg(loop) + strerror(errno) + ")");
 | 
				
			||||||
 | 
					            if (++loop < 10) {
 | 
				
			||||||
 | 
					                QThread::msleep(500);
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ::close(sockfd);
 | 
				
			||||||
 | 
					            return std::nullopt;
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (w > 0) {
 | 
				
			||||||
            int n = ::sendto(sockfd, buf+bytesWritten, bytesToWrite-bytesWritten, 0, NULL, 0);
 | 
					            int n = ::sendto(sockfd, buf+bytesWritten, bytesToWrite-bytesWritten, 0, NULL, 0);
 | 
				
			||||||
            if (n >= 0) {
 | 
					            if (n >= 0) {
 | 
				
			||||||
                bytesWritten += n;
 | 
					                bytesWritten += n;
 | 
				
			||||||
@@ -172,6 +232,7 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // DO NOT USE SHUTDOWN! APISM CAN NOT COPE WITH IT
 | 
					    // DO NOT USE SHUTDOWN! APISM CAN NOT COPE WITH IT
 | 
				
			||||||
    // errno = 0;
 | 
					    // errno = 0;
 | 
				
			||||||
@@ -180,7 +241,7 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
    //        QString("CANNOT CLOSE WRITING END (") + strerror(errno) + ")");
 | 
					    //        QString("CANNOT CLOSE WRITING END (") + strerror(errno) + ")");
 | 
				
			||||||
    // }
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printInfoMessage(port, clientIP, clientPort, QString("MESSAGE SENT ") + buf);
 | 
					    printInfoMessage(port, clientIP, clientPort, QString("MESSAGE SENT <<<") + buf + ">>>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop = 0;
 | 
					    loop = 0;
 | 
				
			||||||
    bzero(buf, sizeof(buf));
 | 
					    bzero(buf, sizeof(buf));
 | 
				
			||||||
@@ -188,6 +249,39 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
    int bytesRead = 0;
 | 
					    int bytesRead = 0;
 | 
				
			||||||
    while (bytesRead < bytesToRead) {
 | 
					    while (bytesRead < bytesToRead) {
 | 
				
			||||||
        errno = 0;
 | 
					        errno = 0;
 | 
				
			||||||
 | 
					        FD_ZERO(&rset);
 | 
				
			||||||
 | 
					        FD_SET(sockfd, &rset);
 | 
				
			||||||
 | 
					        maxfdp1 = sockfd + 1;
 | 
				
			||||||
 | 
					        tv.tv_sec = 60;  /* 60 secs timeout for read and write */
 | 
				
			||||||
 | 
					        tv.tv_usec = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QString const selectStart = QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int const r = select(maxfdp1, &rset, NULL, NULL, &tv);
 | 
				
			||||||
 | 
					        if (r < 0) { // error
 | 
				
			||||||
 | 
					            if (errno == EINTR) {
 | 
				
			||||||
 | 
					                printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                    QString("INTERRUPTED BY SIGNAL (2) (") + strerror(errno) + ")");
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                        QString("SELECT-ERROR (READ) %1(").arg(loop) + strerror(errno) + ")");
 | 
				
			||||||
 | 
					                ::close(sockfd);
 | 
				
			||||||
 | 
					                return std::nullopt;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (r == 0) { // timeout
 | 
				
			||||||
 | 
					            printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
 | 
					                    QString("SELECT-TIMEOUT (READ) %1(").arg(loop) + strerror(errno) + ")");
 | 
				
			||||||
 | 
					            if (++loop < 10) {
 | 
				
			||||||
 | 
					                QThread::msleep(500);
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ::close(sockfd);
 | 
				
			||||||
 | 
					            return std::nullopt;
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (r > 0) {
 | 
				
			||||||
 | 
					            if (FD_ISSET(sockfd, &rset)) {
 | 
				
			||||||
                int n = ::recvfrom(sockfd, buf+bytesRead, bytesToRead-bytesRead,
 | 
					                int n = ::recvfrom(sockfd, buf+bytesRead, bytesToRead-bytesRead,
 | 
				
			||||||
                                   0, NULL, NULL);
 | 
					                                   0, NULL, NULL);
 | 
				
			||||||
                if (n > 0) { //
 | 
					                if (n > 0) { //
 | 
				
			||||||
@@ -196,12 +290,13 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
                if (n == 0) {
 | 
					                if (n == 0) {
 | 
				
			||||||
                    // The return value will be 0 when the peer has performed an orderly shutdown.
 | 
					                    // The return value will be 0 when the peer has performed an orderly shutdown.
 | 
				
			||||||
                    printErrorMessage(port, clientIP, clientPort,
 | 
					                    printErrorMessage(port, clientIP, clientPort,
 | 
				
			||||||
                QString("PEER CLOSED CONNECTION (") + strerror(errno) + ")");
 | 
					                        QString("PEER CLOSED CONNECTION (") + strerror(errno) + ") START AT" +
 | 
				
			||||||
 | 
					                                selectStart + " NOW " + QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
 | 
				
			||||||
                    ::close(sockfd);
 | 
					                    ::close(sockfd);
 | 
				
			||||||
                    return std::nullopt;
 | 
					                    return std::nullopt;
 | 
				
			||||||
                } else
 | 
					                } else
 | 
				
			||||||
                if (n < 0) {
 | 
					                if (n < 0) {
 | 
				
			||||||
            if (errno == EWOULDBLOCK) {
 | 
					                    if (errno == EWOULDBLOCK) { // check just in case
 | 
				
			||||||
                        if (++loop < 10) {
 | 
					                        if (++loop < 10) {
 | 
				
			||||||
                            QThread::msleep(500);
 | 
					                            QThread::msleep(500);
 | 
				
			||||||
                            continue;
 | 
					                            continue;
 | 
				
			||||||
@@ -217,8 +312,10 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
 | 
				
			|||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
 | 
					        // printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
 | 
				
			||||||
        QString response(buf);
 | 
					        QString response(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (int idx = response.indexOf("{\"error\":\"ISMAS is offline\"}")) {
 | 
					        if (int idx = response.indexOf("{\"error\":\"ISMAS is offline\"}")) {
 | 
				
			||||||
@@ -293,16 +390,18 @@ QString IsmasClient::errorBackendNotConnected(QString const &info,
 | 
				
			|||||||
                             version.toStdString().c_str());
 | 
					                             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",
 | 
					    return updateNewsToIsmas("U0003",
 | 
				
			||||||
                             percent,
 | 
					                             m_progressInPercent,
 | 
				
			||||||
                             RESULT_CODE::INSTALL_ERROR,
 | 
					                             RESULT_CODE::INSTALL_ERROR,
 | 
				
			||||||
                             "CLONE CUSTOMER REPOSITORY FAILED",
 | 
					                             "CLONE CUSTOMER REPOSITORY FAILED",
 | 
				
			||||||
                             info.toStdString().c_str(),
 | 
					                             info.toStdString().c_str(),
 | 
				
			||||||
                             version.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",
 | 
					    return updateNewsToIsmas("U0010",
 | 
				
			||||||
                             m_progressInPercent,
 | 
					                             m_progressInPercent,
 | 
				
			||||||
                             RESULT_CODE::SUCCESS,
 | 
					                             RESULT_CODE::SUCCESS,
 | 
				
			||||||
@@ -311,7 +410,8 @@ QString IsmasClient::backendConnected(QString const &info, QString const &versio
 | 
				
			|||||||
                             version.toStdString().c_str());
 | 
					                             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",
 | 
					    return updateNewsToIsmas("U0010",
 | 
				
			||||||
                             m_progressInPercent,
 | 
					                             m_progressInPercent,
 | 
				
			||||||
                             RESULT_CODE::SUCCESS,
 | 
					                             RESULT_CODE::SUCCESS,
 | 
				
			||||||
@@ -320,6 +420,15 @@ QString IsmasClient::execOpkgCommand(QString const &info, QString const &version
 | 
				
			|||||||
                             version.toStdString().c_str());
 | 
					                             version.toStdString().c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString IsmasClient::rsyncFile(QString const &info, QString const &version) {
 | 
				
			||||||
 | 
					    return updateNewsToIsmas("U0010",
 | 
				
			||||||
 | 
					                             m_progressInPercent,
 | 
				
			||||||
 | 
					                             RESULT_CODE::SUCCESS,
 | 
				
			||||||
 | 
					                             "RSYNC FILE",
 | 
				
			||||||
 | 
					                             info.toStdString().c_str(),
 | 
				
			||||||
 | 
					                             version.toStdString().c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString IsmasClient::updateTriggerSet(QString const &info, QString const &version) {
 | 
					QString IsmasClient::updateTriggerSet(QString const &info, QString const &version) {
 | 
				
			||||||
    return updateNewsToIsmas("U0010",
 | 
					    return updateNewsToIsmas("U0010",
 | 
				
			||||||
                             m_progressInPercent,
 | 
					                             m_progressInPercent,
 | 
				
			||||||
@@ -345,13 +454,11 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
 | 
				
			|||||||
    static char buf[4096*2];
 | 
					    static char buf[4096*2];
 | 
				
			||||||
    memset(buf, 0, sizeof(buf));
 | 
					    memset(buf, 0, sizeof(buf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString const ts = QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
 | 
					 | 
				
			||||||
    QString sendVersionHash = "N/A";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // local data="#M=APISM#C=CMD_SENDVERSION#J=
 | 
					    // local data="#M=APISM#C=CMD_SENDVERSION#J=
 | 
				
			||||||
    snprintf(buf, sizeof(buf)-1,
 | 
					    snprintf(buf, sizeof(buf)-1,
 | 
				
			||||||
        "{"
 | 
					        "{"
 | 
				
			||||||
            "\"VERSION_INFO\" : {"
 | 
					            "\"VERSION_INFO\" : {"
 | 
				
			||||||
 | 
					                "\"REASON\":\"%s\","
 | 
				
			||||||
                "\"CREATED\":\"%s\","
 | 
					                "\"CREATED\":\"%s\","
 | 
				
			||||||
                "\"HASH\":\"%s\""
 | 
					                "\"HASH\":\"%s\""
 | 
				
			||||||
            "},"
 | 
					            "},"
 | 
				
			||||||
@@ -361,6 +468,13 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
 | 
				
			|||||||
                "\"ZONE\" : %d,"
 | 
					                "\"ZONE\" : %d,"
 | 
				
			||||||
                "\"INFO\" : \"%s\","
 | 
					                "\"INFO\" : \"%s\","
 | 
				
			||||||
                "\"BLOB\" : \"%s\","
 | 
					                "\"BLOB\" : \"%s\","
 | 
				
			||||||
 | 
					                "\"LAST-COMMIT\" : \"%s\","
 | 
				
			||||||
 | 
					                "\"SIZE\" : %d,"
 | 
				
			||||||
 | 
					                "\"LOADED\" : \"%s\""
 | 
				
			||||||
 | 
					            "},"
 | 
				
			||||||
 | 
					            "\"OPKG_COMMANDS\" : {"
 | 
				
			||||||
 | 
					                "\"BLOB\" : \"%s\","
 | 
				
			||||||
 | 
					                "\"LAST-COMMIT\" : \"%s\","
 | 
				
			||||||
                "\"SIZE\" : %d,"
 | 
					                "\"SIZE\" : %d,"
 | 
				
			||||||
                "\"LOADED\" : \"%s\""
 | 
					                "\"LOADED\" : \"%s\""
 | 
				
			||||||
            "},"
 | 
					            "},"
 | 
				
			||||||
@@ -529,10 +643,14 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
 | 
				
			|||||||
                "}"
 | 
					                "}"
 | 
				
			||||||
            "},"
 | 
					            "},"
 | 
				
			||||||
            "\"SOFTWARE\": {"
 | 
					            "\"SOFTWARE\": {"
 | 
				
			||||||
                "\"RAUC\" : \"%s\","
 | 
					                "\"APISM\" : {"
 | 
				
			||||||
                "\"OPKG\" : \"%s\","
 | 
					                    "\"VERSION\" : \"%s\""
 | 
				
			||||||
 | 
					                "},"
 | 
				
			||||||
                "\"ATBQT\" : {"
 | 
					                "\"ATBQT\" : {"
 | 
				
			||||||
                    "\"VERSION\" : \"%s\""
 | 
					                    "\"VERSION\" : \"%s\""
 | 
				
			||||||
 | 
					                "},"
 | 
				
			||||||
 | 
					                "\"ATB-UPDATE-TOOL\" : {"
 | 
				
			||||||
 | 
					                    "\"VERSION\" : \"%s\""
 | 
				
			||||||
                "}"
 | 
					                "}"
 | 
				
			||||||
            "},"
 | 
					            "},"
 | 
				
			||||||
            "\"PLUGINS\" : {"
 | 
					            "\"PLUGINS\" : {"
 | 
				
			||||||
@@ -559,17 +677,24 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
 | 
				
			|||||||
                "}"
 | 
					                "}"
 | 
				
			||||||
            "}"
 | 
					            "}"
 | 
				
			||||||
        "}",
 | 
					        "}",
 | 
				
			||||||
        ts.toStdString().c_str(),
 | 
					        psa.versionInfo.reason.toStdString().c_str(),
 | 
				
			||||||
        sendVersionHash.toStdString().c_str(),
 | 
					        psa.versionInfo.created.toStdString().c_str(),
 | 
				
			||||||
 | 
					        psa.versionInfo.lastCommit.toStdString().c_str(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        psa.tariff.version.toStdString().c_str(),
 | 
					        psa.tariff.version.toStdString().c_str(),
 | 
				
			||||||
        psa.tariff.project.toStdString().c_str(),
 | 
					        psa.tariff.project.toStdString().c_str(),
 | 
				
			||||||
        psa.tariff.zone,
 | 
					        psa.tariff.zone,
 | 
				
			||||||
        psa.tariff.info.toStdString().c_str(),
 | 
					        psa.tariff.info.toStdString().c_str(),
 | 
				
			||||||
        psa.tariff.blob.toStdString().c_str(),
 | 
					        psa.tariff.blob.toStdString().c_str(),
 | 
				
			||||||
 | 
					        psa.tariff.lastCommit.toStdString().c_str(),
 | 
				
			||||||
        psa.tariff.size,
 | 
					        psa.tariff.size,
 | 
				
			||||||
        psa.tariff.loadTime.toStdString().c_str(),
 | 
					        psa.tariff.loadTime.toStdString().c_str(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        psa.opkg.blob.toStdString().c_str(),
 | 
				
			||||||
 | 
					        psa.opkg.lastCommit.toStdString().c_str(),
 | 
				
			||||||
 | 
					        psa.opkg.size,
 | 
				
			||||||
 | 
					        psa.opkg.loadTime.toStdString().c_str(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        psa.cash.blob.toStdString().c_str(),
 | 
					        psa.cash.blob.toStdString().c_str(),
 | 
				
			||||||
        psa.cash.size,
 | 
					        psa.cash.size,
 | 
				
			||||||
        psa.conf.blob.toStdString().c_str(),
 | 
					        psa.conf.blob.toStdString().c_str(),
 | 
				
			||||||
@@ -651,9 +776,9 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
 | 
				
			|||||||
        psa.dc.gitBlob.toStdString().c_str(),
 | 
					        psa.dc.gitBlob.toStdString().c_str(),
 | 
				
			||||||
        psa.dc.gitLastCommit.toStdString().c_str(),
 | 
					        psa.dc.gitLastCommit.toStdString().c_str(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        psa.sw.raucVersion.toStdString().c_str(),
 | 
					        psa.sw.apismVersion.toStdString().c_str(),
 | 
				
			||||||
        psa.sw.opkgVersion.toStdString().c_str(),
 | 
					 | 
				
			||||||
        psa.sw.atbQTVersion.toStdString().c_str(),
 | 
					        psa.sw.atbQTVersion.toStdString().c_str(),
 | 
				
			||||||
 | 
					        psa.sw.atbUpdateToolVersion.toStdString().c_str(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        psa.pluginVersion.deviceController.toStdString().c_str(),
 | 
					        psa.pluginVersion.deviceController.toStdString().c_str(),
 | 
				
			||||||
        psa.pluginVersion.ingenicoISelfCC.toStdString().c_str(),
 | 
					        psa.pluginVersion.ingenicoISelfCC.toStdString().c_str(),
 | 
				
			||||||
@@ -735,7 +860,7 @@ QString IsmasClient::updateOfPSAActivated(QString const &version) {   // sent ev
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString IsmasClient::updateOfPSASucceeded(QString const &version) {
 | 
					QString IsmasClient::updateOfPSASucceeded(QString const &version) {
 | 
				
			||||||
    m_progressInPercent = 0;
 | 
					    m_progressInPercent = 100;
 | 
				
			||||||
    return updateNewsToIsmas("U0001",
 | 
					    return updateNewsToIsmas("U0001",
 | 
				
			||||||
                             m_progressInPercent,
 | 
					                             m_progressInPercent,
 | 
				
			||||||
                             RESULT_CODE::SUCCESS,
 | 
					                             RESULT_CODE::SUCCESS,
 | 
				
			||||||
@@ -762,14 +887,21 @@ QString IsmasClient::jsonParseFailed(int resultCode, QString reason, QString con
 | 
				
			|||||||
                             version.toStdString().c_str());
 | 
					                             version.toStdString().c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::optional<QString> IsmasClient::finalResult(int resultCode, QString reason, QString const &version) {
 | 
					std::optional<QString> IsmasClient::finalResult(int resultCode,
 | 
				
			||||||
    m_progressInPercent = 0;
 | 
					                                                QString reason,
 | 
				
			||||||
 | 
					                                                QString const &version) {
 | 
				
			||||||
 | 
					    Q_UNUSED(resultCode);
 | 
				
			||||||
 | 
					    Q_UNUSED(reason);
 | 
				
			||||||
 | 
					    Q_UNUSED(version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    m_progressInPercent = 100;
 | 
				
			||||||
    if (resultCode == RESULT_CODE::SUCCESS) {
 | 
					    if (resultCode == RESULT_CODE::SUCCESS) {
 | 
				
			||||||
        return updateNewsToIsmas("U0002",
 | 
					        return updateNewsToIsmas("U0002",
 | 
				
			||||||
                                 m_progressInPercent,
 | 
					                                 m_progressInPercent,
 | 
				
			||||||
                                 RESULT_CODE::SUCCESS,
 | 
					                                 resultCode,
 | 
				
			||||||
                                 "FINAL-UPDATE-RESULT",
 | 
					                                 "FINAL-UPDATE-RESULT",
 | 
				
			||||||
                                 "(re-)set WAIT state",
 | 
					                                 reason.toStdString().c_str(),
 | 
				
			||||||
                                 version.toStdString().c_str());
 | 
					                                 version.toStdString().c_str());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (resultCode == RESULT_CODE::INSTALL_ERROR) {
 | 
					    if (resultCode == RESULT_CODE::INSTALL_ERROR) {
 | 
				
			||||||
@@ -780,6 +912,7 @@ std::optional<QString> IsmasClient::finalResult(int resultCode, QString reason,
 | 
				
			|||||||
                                 reason.toStdString().c_str(),
 | 
					                                 reason.toStdString().c_str(),
 | 
				
			||||||
                                 version.toStdString().c_str());
 | 
					                                 version.toStdString().c_str());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
    return std::nullopt;
 | 
					    return std::nullopt;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -792,3 +925,18 @@ QString IsmasClient::updateOfPSAFailed(int resultCode, QString step,
 | 
				
			|||||||
                             reason.toStdString().c_str(),
 | 
					                             reason.toStdString().c_str(),
 | 
				
			||||||
                             version.toStdString().c_str());
 | 
					                             version.toStdString().c_str());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char const *IsmasClient::reason[REASON::ENTRIES] = {
 | 
				
			||||||
 | 
					    "TIME-TRIGGERED", "SERVICE", "DEV-TEST"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString IsmasClient::getReasonForLastSendVersion() {
 | 
				
			||||||
 | 
					    QString const &parentName = Utils::getParentName();
 | 
				
			||||||
 | 
					    if (parentName == "ATBQT") {
 | 
				
			||||||
 | 
					        return reason[REASON::SERVICE];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (parentName == "systemd") {
 | 
				
			||||||
 | 
					        return reason[REASON::TIME_TRIGGERED];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return reason[REASON::DEV_TEST];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,12 @@
 | 
				
			|||||||
#include <optional>
 | 
					#include <optional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PSAInstalled {
 | 
					struct PSAInstalled {
 | 
				
			||||||
 | 
					    struct VersionInfo {
 | 
				
			||||||
 | 
					        QString created;
 | 
				
			||||||
 | 
					        QString reason;
 | 
				
			||||||
 | 
					        QString lastCommit;
 | 
				
			||||||
 | 
					    } versionInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct Tariff {
 | 
					    struct Tariff {
 | 
				
			||||||
        QString name;
 | 
					        QString name;
 | 
				
			||||||
        QString version;
 | 
					        QString version;
 | 
				
			||||||
@@ -24,6 +30,13 @@ struct PSAInstalled {
 | 
				
			|||||||
        QString cpuSerial;
 | 
					        QString cpuSerial;
 | 
				
			||||||
    } hw;
 | 
					    } hw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct Opkg {
 | 
				
			||||||
 | 
					        int size;
 | 
				
			||||||
 | 
					        QString blob;
 | 
				
			||||||
 | 
					        QString lastCommit;
 | 
				
			||||||
 | 
					        QString loadTime;
 | 
				
			||||||
 | 
					    } opkg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct DC {
 | 
					    struct DC {
 | 
				
			||||||
        QString versionHW;
 | 
					        QString versionHW;
 | 
				
			||||||
        QString versionSW;
 | 
					        QString versionSW;
 | 
				
			||||||
@@ -33,9 +46,9 @@ struct PSAInstalled {
 | 
				
			|||||||
    } dc;
 | 
					    } dc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct SoftWare {
 | 
					    struct SoftWare {
 | 
				
			||||||
        QString raucVersion;
 | 
					        QString apismVersion;
 | 
				
			||||||
        QString opkgVersion;
 | 
					 | 
				
			||||||
        QString atbQTVersion;
 | 
					        QString atbQTVersion;
 | 
				
			||||||
 | 
					        QString atbUpdateToolVersion;
 | 
				
			||||||
    } sw;
 | 
					    } sw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct PluginVersion {
 | 
					    struct PluginVersion {
 | 
				
			||||||
@@ -73,15 +86,20 @@ struct PSAInstalled {
 | 
				
			|||||||
        hw.linuxVersion = "N/A";
 | 
					        hw.linuxVersion = "N/A";
 | 
				
			||||||
        hw.cpuSerial = "N/A";
 | 
					        hw.cpuSerial = "N/A";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        opkg.size = -1;
 | 
				
			||||||
 | 
					        opkg.blob = "N/A";
 | 
				
			||||||
 | 
					        opkg.lastCommit = "N/A";
 | 
				
			||||||
 | 
					        opkg.loadTime = "N/A";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dc.versionHW = "N/A";
 | 
					        dc.versionHW = "N/A";
 | 
				
			||||||
        dc.versionSW = "N/A";
 | 
					        dc.versionSW = "N/A";
 | 
				
			||||||
        dc.gitBlob = "N/A";
 | 
					        dc.gitBlob = "N/A";
 | 
				
			||||||
        dc.gitLastCommit = "N/A";
 | 
					        dc.gitLastCommit = "N/A";
 | 
				
			||||||
        dc.size = -1;
 | 
					        dc.size = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sw.raucVersion = "N/A";
 | 
					        sw.apismVersion = "N/A";
 | 
				
			||||||
        sw.opkgVersion = "N/A";
 | 
					 | 
				
			||||||
        sw.atbQTVersion = "N/A";
 | 
					        sw.atbQTVersion = "N/A";
 | 
				
			||||||
 | 
					        sw.atbUpdateToolVersion = "N/A";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pluginVersion.deviceController = "N/A";
 | 
					        pluginVersion.deviceController = "N/A";
 | 
				
			||||||
        pluginVersion.ingenicoISelfCC = "N/A";
 | 
					        pluginVersion.ingenicoISelfCC = "N/A";
 | 
				
			||||||
@@ -123,6 +141,7 @@ public:
 | 
				
			|||||||
        DIRECT_PORT = 7778
 | 
					        DIRECT_PORT = 7778
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum RESULT_CODE {
 | 
					    enum RESULT_CODE {
 | 
				
			||||||
        SUCCESS=0,
 | 
					        SUCCESS=0,
 | 
				
			||||||
        NO_UPDATE_NECESSARY=1,
 | 
					        NO_UPDATE_NECESSARY=1,
 | 
				
			||||||
@@ -130,9 +149,20 @@ public:
 | 
				
			|||||||
        WRONG_PACKAGE=3,
 | 
					        WRONG_PACKAGE=3,
 | 
				
			||||||
        INSTALL_ERROR=4};
 | 
					        INSTALL_ERROR=4};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum REASON {
 | 
				
			||||||
 | 
					        TIME_TRIGGERED = 0,
 | 
				
			||||||
 | 
					        SERVICE,
 | 
				
			||||||
 | 
					        DEV_TEST,
 | 
				
			||||||
 | 
					        ENTRIES
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static char const *reason[REASON::ENTRIES];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static std::optional<QString>
 | 
					    static std::optional<QString>
 | 
				
			||||||
        sendRequestReceiveResponse(int port, QString const &request);
 | 
					        sendRequestReceiveResponse(int port, QString const &request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static QString getReasonForLastSendVersion();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int getProgressInPercent() const {return m_progressInPercent; }
 | 
					    int getProgressInPercent() const {return m_progressInPercent; }
 | 
				
			||||||
    void setProgressInPercent(int procent) { m_progressInPercent = procent; }
 | 
					    void setProgressInPercent(int procent) { m_progressInPercent = procent; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,12 +177,13 @@ public:
 | 
				
			|||||||
    QString cloneAndCheckoutCustomerRepository(QString const &info, QString const &version = QString());   // clone and checkout customer repository
 | 
					    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 checkoutBranch(QString const &info, QString const &version = QString());   // checkout branch
 | 
				
			||||||
    QString errorBackendNotConnected(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 backendConnected(QString const &info, QString const &version = QString());
 | 
				
			||||||
    QString updateTriggerSet(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());
 | 
					    QString errorUpdateTrigger(QString const &info, QString const &version = QString());
 | 
				
			||||||
    QString gitFetch(QString const &info, QString const &version = QString());
 | 
					    QString gitFetch(QString const &info, QString const &version = QString());
 | 
				
			||||||
    QString execOpkgCommand(QString const &info, QString const &version = QString());
 | 
					    QString execOpkgCommand(QString const &info, QString const &version = QString());
 | 
				
			||||||
 | 
					    QString rsyncFile(QString const &info, QString const &version = QString());
 | 
				
			||||||
    QString errorGitFetch(int resultCode, QString const &info, QString const &version = QString());
 | 
					    QString errorGitFetch(int resultCode, QString const &info, QString const &version = QString());
 | 
				
			||||||
    QString updateOfPSAActivated(QString const &version = QString());
 | 
					    QString updateOfPSAActivated(QString const &version = QString());
 | 
				
			||||||
                                    // and update accepted
 | 
					                                    // and update accepted
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										113
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								main.cpp
									
									
									
									
									
								
							@@ -31,6 +31,13 @@
 | 
				
			|||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QThread>
 | 
					#include <QThread>
 | 
				
			||||||
 | 
					#include <QtWidgets>
 | 
				
			||||||
 | 
					#include <QScopedPointer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef PTU5
 | 
					#ifdef PTU5
 | 
				
			||||||
#define SERIAL_PORT "ttymxc2"
 | 
					#define SERIAL_PORT "ttymxc2"
 | 
				
			||||||
@@ -65,21 +72,25 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
    QCommandLineOption pluginDirectoryOption(QStringList() << "plugin-directory" << "plugin-directory",
 | 
					    QCommandLineOption pluginDirectoryOption(QStringList() << "plugin-directory" << "plugin-directory",
 | 
				
			||||||
        QCoreApplication::translate("main", "Where to find dc-plugin."),
 | 
					        QCoreApplication::translate("main", "Where to find dc-plugin."),
 | 
				
			||||||
        QCoreApplication::translate("main", "directory"));
 | 
					        QCoreApplication::translate("main", "directory"));
 | 
				
			||||||
    QString const pluginDefault = "./plugins";
 | 
					    QString const pluginDefault = "/usr/lib";
 | 
				
			||||||
    pluginDirectoryOption.setDefaultValue(pluginDefault);
 | 
					    pluginDirectoryOption.setDefaultValue(pluginDefault);
 | 
				
			||||||
    parser.addOption(pluginDirectoryOption);
 | 
					    parser.addOption(pluginDirectoryOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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",
 | 
					    QCommandLineOption workingDirectoryOption(QStringList() << "working-directory" << "working-directory",
 | 
				
			||||||
        QCoreApplication::translate("main", "working directory of update-script."),
 | 
					        QCoreApplication::translate("main", "working directory of update-script."),
 | 
				
			||||||
        QCoreApplication::translate("main", "directory"));
 | 
					        QCoreApplication::translate("main", "directory"));
 | 
				
			||||||
    QString const workingDirectoryDefault = ".";
 | 
					    QString const workingDirectoryDefault = "/opt/app/tools/atbupdate";
 | 
				
			||||||
    workingDirectoryOption.setDefaultValue(workingDirectoryDefault);
 | 
					    workingDirectoryOption.setDefaultValue(workingDirectoryDefault);
 | 
				
			||||||
    parser.addOption(workingDirectoryOption);
 | 
					    parser.addOption(workingDirectoryOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,47 +98,30 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
        QCoreApplication::translate("main", "Start ATBUpdateTool in dry-run-mode. No actual actions."));
 | 
					        QCoreApplication::translate("main", "Start ATBUpdateTool in dry-run-mode. No actual actions."));
 | 
				
			||||||
    parser.addOption(dryRunOption);
 | 
					    parser.addOption(dryRunOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO:
 | 
					    QCommandLineOption extendedVersionOption(QStringList() << "V" << "extended-version",
 | 
				
			||||||
    // add some additional parameters
 | 
					        QCoreApplication::translate("main", "Show extended version (including last git commit)."));
 | 
				
			||||||
    // --dry-run
 | 
					    parser.addOption(extendedVersionOption);
 | 
				
			||||||
    // -d: only update device-controller firmware
 | 
					
 | 
				
			||||||
    // -j: only update json-files
 | 
					    QCommandLineOption yoctoVersionOption(QStringList() << "y" << "yocto-version",
 | 
				
			||||||
    // -o: only execute opkg-commnds
 | 
					        QCoreApplication::translate("main", "Show yocto version of ATBUpdateTool."));
 | 
				
			||||||
    // -f: force. update_psa shall always perform a 'git pull'
 | 
					    parser.addOption(yoctoVersionOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QCommandLineOption yoctoInstallStatusOption(QStringList() << "Y" << "yocto-install",
 | 
				
			||||||
 | 
					        QCoreApplication::translate("main", "Show yocto install status of ATBUpdateTool."));
 | 
				
			||||||
 | 
					    parser.addOption(yoctoInstallStatusOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Process the actual command line arguments given by the user
 | 
					    // Process the actual command line arguments given by the user
 | 
				
			||||||
    parser.process(a);
 | 
					    parser.process(a);
 | 
				
			||||||
    QString plugInDir = parser.value(pluginDirectoryOption);
 | 
					    QString plugInDir = parser.value(pluginDirectoryOption);
 | 
				
			||||||
    QString plugInName = parser.value(pluginNameOption);
 | 
					    QString plugInName = parser.value(pluginNameOption);
 | 
				
			||||||
    QString workingDir = parser.value(workingDirectoryOption);
 | 
					    QString workingDir = parser.value(workingDirectoryOption);
 | 
				
			||||||
    bool dryRun = parser.isSet(dryRunOption);
 | 
					    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);
 | 
				
			||||||
    QString const rtPath = QCoreApplication::applicationDirPath();
 | 
					    QString const rtPath = QCoreApplication::applicationDirPath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (plugInDir == pluginDefault) {
 | 
					 | 
				
			||||||
        plugInDir = (rtPath + "/" + pluginDefault);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (!QDir(plugInDir).exists()) {
 | 
					 | 
				
			||||||
        qCritical() << plugInDir
 | 
					 | 
				
			||||||
                    << "does not exists, but has to contain dc-library";
 | 
					 | 
				
			||||||
        exit(-1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    qInfo() << "pwd ..............." << rtPath;
 | 
					 | 
				
			||||||
    qInfo() << "plugInDir ........." << plugInDir;
 | 
					 | 
				
			||||||
    qInfo() << "plugInName ........" << plugInName;
 | 
					 | 
				
			||||||
    qInfo() << "workingDir ........" << workingDir;
 | 
					 | 
				
			||||||
    qInfo() << "dryRun ............" << dryRun;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // before loading the library, delete all possible shared memory segments
 | 
					 | 
				
			||||||
#if defined Q_OS_LINUX || defined Q_OS_UNIX
 | 
					 | 
				
			||||||
    // system("rm -rf /tmp/qipc*");
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#error "Only tested under UNIX/LINUX"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
 | 
					 | 
				
			||||||
    // hw->dc_autoRequest(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
 | 
					    int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
 | 
				
			||||||
    int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
 | 
					    int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
 | 
				
			||||||
    int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
 | 
					    int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
 | 
				
			||||||
@@ -137,20 +131,59 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
    QThread::currentThread()->setObjectName("main thread");
 | 
					    QThread::currentThread()->setObjectName("main thread");
 | 
				
			||||||
    qInfo() << "Main thread" << QThread::currentThreadId();
 | 
					    qInfo() << "Main thread" << QThread::currentThreadId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Worker worker(hw,
 | 
					    if (showExtendedVersion) {
 | 
				
			||||||
                  customerNr,
 | 
					        printf(APP_EXTENDED_VERSION"\n");
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (showYoctoVersion) {
 | 
				
			||||||
 | 
					        printf("%s\n", Worker::getATBUpdateToolYoctoVersion().toStdString().c_str());
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (showYoctoInstallStatus) {
 | 
				
			||||||
 | 
					        printf("%s\n", Worker::getATBUpdateToolYoctoInstallationStatus().toStdString().c_str());
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!QDir(plugInDir).exists()) {
 | 
				
			||||||
 | 
					        qCritical() << plugInDir
 | 
				
			||||||
 | 
					                    << "does not exists, but has to contain dc-library";
 | 
				
			||||||
 | 
					        exit(-1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qInfo() << "pwd ......................" << rtPath;
 | 
				
			||||||
 | 
					    qInfo() << "plugInDir ................" << plugInDir;
 | 
				
			||||||
 | 
					    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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // before loading the library, delete all possible shared memory segments
 | 
				
			||||||
 | 
					#if defined Q_OS_LINUX || defined Q_OS_UNIX
 | 
				
			||||||
 | 
					    // system("rm -rf /tmp/qipc*");
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#error "Only tested under UNIX/LINUX"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Worker worker(customerNr,
 | 
				
			||||||
                  machineNr,
 | 
					                  machineNr,
 | 
				
			||||||
                  zoneNr,
 | 
					                  zoneNr,
 | 
				
			||||||
                  branchName,
 | 
					                  branchName,
 | 
				
			||||||
 | 
					                  plugInDir,
 | 
				
			||||||
 | 
					                  plugInName,
 | 
				
			||||||
                  workingDir,
 | 
					                  workingDir,
 | 
				
			||||||
 | 
					                  noUpdatePsaHardware,
 | 
				
			||||||
                  dryRun);
 | 
					                  dryRun);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MainWindow mw(&worker);
 | 
					    MainWindow mw(&worker);
 | 
				
			||||||
    worker.setMainWindow(&mw);
 | 
					    worker.setMainWindow(&mw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
 | 
					    mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
 | 
				
			||||||
    mw.setWindowState(Qt::WindowFullScreen);
 | 
					    mw.showFullScreen();
 | 
				
			||||||
    mw.show();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return a.exec();
 | 
					    return a.exec();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										194
									
								
								mainwindow.cpp
									
									
									
									
									
								
							
							
						
						
									
										194
									
								
								mainwindow.cpp
									
									
									
									
									
								
							@@ -3,10 +3,15 @@
 | 
				
			|||||||
#include "worker.h"
 | 
					#include "worker.h"
 | 
				
			||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
#include "progress_event.h"
 | 
					#include "progress_event.h"
 | 
				
			||||||
 | 
					#include "update_dc_event.h"
 | 
				
			||||||
 | 
					#include "plugins/interfaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QDateTime>
 | 
					#include <QDateTime>
 | 
				
			||||||
#include <QMessageBox>
 | 
					#include <QMessageBox>
 | 
				
			||||||
#include <QDebug>
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QScrollBar>
 | 
				
			||||||
 | 
					#include <QEvent>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
					MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
				
			||||||
    : QMainWindow(parent)
 | 
					    : QMainWindow(parent)
 | 
				
			||||||
@@ -14,7 +19,16 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
				
			|||||||
    , m_worker(worker)
 | 
					    , m_worker(worker)
 | 
				
			||||||
    , m_width(70)
 | 
					    , m_width(70)
 | 
				
			||||||
    , m_progressRunning(false)
 | 
					    , m_progressRunning(false)
 | 
				
			||||||
    , m_progressValue(0) {
 | 
					    , m_updateStep(UpdateDcEvent::UpdateStep::NONE) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this->setStatusBar(new QStatusBar(this));
 | 
				
			||||||
 | 
					    QFont f;
 | 
				
			||||||
 | 
					    f.setStyleHint(QFont::Monospace);
 | 
				
			||||||
 | 
					    f.setWeight(QFont::Bold);
 | 
				
			||||||
 | 
					    f.setFamily("Misc Fixed");
 | 
				
			||||||
 | 
					    f.setPixelSize(12);
 | 
				
			||||||
 | 
					    this->statusBar()->setFont(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ui->setupUi(this);
 | 
					    ui->setupUi(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ui->updateProgress->setRange(0, 100);
 | 
					    ui->updateProgress->setRange(0, 100);
 | 
				
			||||||
@@ -24,16 +38,19 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
				
			|||||||
    QString start = QDateTime::currentDateTime().toString(Qt::ISODate);
 | 
					    QString start = QDateTime::currentDateTime().toString(Qt::ISODate);
 | 
				
			||||||
    lst << QString("Start: ") + start.leftJustified(m_width-10);
 | 
					    lst << QString("Start: ") + start.leftJustified(m_width-10);
 | 
				
			||||||
    lst << QString("").leftJustified(m_width-3, '=');
 | 
					    lst << QString("").leftJustified(m_width-3, '=');
 | 
				
			||||||
 | 
					    lst << QString("Update tool version: %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).leftJustified(m_width-3);
 | 
				
			||||||
    lst << QString("Machine number     : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3);
 | 
					    lst << QString("Machine number     : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3);
 | 
				
			||||||
    lst << QString("Customer number    : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3);
 | 
					    lst << QString("Customer number    : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3);
 | 
				
			||||||
    lst << QString("Zone number        : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
 | 
					    lst << QString("Zone number        : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
 | 
				
			||||||
 | 
					    lst << QString("APISM version      : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3);
 | 
				
			||||||
    lst << QString("").leftJustified(m_width-3, '=');
 | 
					    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(start()));
 | 
				
			||||||
    m_startTimer->setSingleShot(true);
 | 
					    m_startTimer->setSingleShot(true);
 | 
				
			||||||
    m_startTimer->start(1000);
 | 
					    m_startTimer->start(1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,10 +66,11 @@ MainWindow::MainWindow(Worker *worker, QWidget *parent)
 | 
				
			|||||||
    connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer()));
 | 
					    connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer()));
 | 
				
			||||||
    connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString)));
 | 
					    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(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(QString,QString)),this,SLOT(onReplaceLast(QString,QString)));
 | 
				
			||||||
 | 
					    connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString)));
 | 
				
			||||||
    ui->updateStatus->setText(lst.join('\n'));
 | 
					 | 
				
			||||||
    ui->updateStatus->setEnabled(true);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MainWindow::~MainWindow() {
 | 
					MainWindow::~MainWindow() {
 | 
				
			||||||
@@ -74,22 +92,22 @@ void MainWindow::customEvent(QEvent *event) {
 | 
				
			|||||||
            case START_PROGRESS_LOOP: {
 | 
					            case START_PROGRESS_LOOP: {
 | 
				
			||||||
                m_progressRunning = true;
 | 
					                m_progressRunning = true;
 | 
				
			||||||
                ui->updateProgress->reset();
 | 
					                ui->updateProgress->reset();
 | 
				
			||||||
                m_progressValue = 10;
 | 
					                // m_progressValue = 10;
 | 
				
			||||||
                QApplication::postEvent(this, new ProgressEvent(this, m_progressValue));
 | 
					                QApplication::postEvent(this, new ProgressEvent(this, 1));
 | 
				
			||||||
            } break;
 | 
					            } break;
 | 
				
			||||||
            case STOP_PROGRESS_LOOP: {
 | 
					            case STOP_PROGRESS_LOOP: {
 | 
				
			||||||
                m_progressRunning = false;
 | 
					                m_progressRunning = false;
 | 
				
			||||||
                m_progressValue -= 10;
 | 
					                // m_progressValue -= 10;
 | 
				
			||||||
                m_worker->setProgress(m_progressValue/10);
 | 
					                // m_worker->setProgress(m_progressValue/10);
 | 
				
			||||||
            } break;
 | 
					            } break;
 | 
				
			||||||
            default: {
 | 
					            default: {
 | 
				
			||||||
                if (m_progressRunning) {
 | 
					                if (m_progressRunning) {
 | 
				
			||||||
                        m_progressValue = progress;
 | 
					                    // m_progressValue = progress;
 | 
				
			||||||
                        ui->updateProgress->setValue(progress/10);
 | 
					                    ui->updateProgress->setValue(progress);
 | 
				
			||||||
                        QApplication::postEvent(this, new ProgressEvent(this, progress+10));
 | 
					                    // ueberpruefen: hauptfenster schickt sich selber ein event
 | 
				
			||||||
                        QThread::msleep(500);
 | 
					                    // QApplication::postEvent(this, new ProgressEvent(this, progress));
 | 
				
			||||||
                    }
 | 
					                    // QThread::msleep(500);
 | 
				
			||||||
                }
 | 
					                }}
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else
 | 
					        } else
 | 
				
			||||||
        if (sender == m_worker) {
 | 
					        if (sender == m_worker) {
 | 
				
			||||||
@@ -129,69 +147,159 @@ void MainWindow::onEnableExit() {
 | 
				
			|||||||
void MainWindow::onRestartExitTimer() {
 | 
					void MainWindow::onRestartExitTimer() {
 | 
				
			||||||
    m_exitTimer->stop();
 | 
					    m_exitTimer->stop();
 | 
				
			||||||
    m_exitTimer->start(60 * 1000);
 | 
					    m_exitTimer->start(60 * 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scrollDownTextEdit();
 | 
				
			||||||
 | 
					    ui->updateStatus->setEnabled(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onQuit() {
 | 
					void MainWindow::onQuit() {
 | 
				
			||||||
    m_exitTimer->stop();
 | 
					    m_exitTimer->stop();
 | 
				
			||||||
    qCritical() << QString("ON QUIT: EXIT CODE %1").arg(m_worker->returnCode());
 | 
					    int errorCode = 0;
 | 
				
			||||||
    qApp->exit(m_worker->returnCode());
 | 
					
 | 
				
			||||||
 | 
					    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() {
 | 
				
			||||||
 | 
					    // Utils::printInfoMsg(QString("SCROLL-DOWN-TEXT_EDIT CALLED AT ")
 | 
				
			||||||
 | 
					    //    + QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ui->updateStatus->setEnabled(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QTextCursor tmpCursor = ui->updateStatus->textCursor();
 | 
				
			||||||
 | 
					    tmpCursor.movePosition(QTextCursor::End);
 | 
				
			||||||
 | 
					    ui->updateStatus->setTextCursor(tmpCursor);
 | 
				
			||||||
 | 
					    ui->updateStatus->ensureCursorVisible();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onAppendText(QString text, QString suffix) {
 | 
					void MainWindow::onAppendText(QString text, QString suffix) {
 | 
				
			||||||
 | 
					    // Utils::printInfoMsg(QString("ON APPEND CALLED AT ")
 | 
				
			||||||
 | 
					    //    + QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString editText = ui->updateStatus->toPlainText();
 | 
					    QString editText = ui->updateStatus->toPlainText();
 | 
				
			||||||
 | 
					    scrollDownTextEdit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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 += " ";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        editText += (QString("\n") + text).leftJustified(m_width - (2 + suffix.size()) ) + suffix;
 | 
					        QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix;
 | 
				
			||||||
 | 
					        ui->updateStatus->insertPlainText(add);
 | 
				
			||||||
 | 
					        // editText += add;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        editText += text.leftJustified(m_width-9);
 | 
					        QString const &add = text.leftJustified(m_width-9);
 | 
				
			||||||
 | 
					        ui->updateStatus->insertPlainText(add);
 | 
				
			||||||
 | 
					        //editText += add;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Utils::printLineEditInfo(editText.split('\n'));
 | 
					    // debug
 | 
				
			||||||
 | 
					    // QString editText = ui->updateStatus->toPlainText();
 | 
				
			||||||
 | 
					    // Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts));
 | 
				
			||||||
 | 
					    // ui->updateStatus->setText(editText.trimmed());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ui->updateStatus->setPlainText(editText.trimmed());
 | 
					    // scrollDownTextEdit();
 | 
				
			||||||
    ui->updateStatus->setEnabled(true);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) {
 | 
				
			||||||
 | 
					    // Utils::printInfoMsg(QString("ON REPLACE LAST (LIST) CALLED AT ")
 | 
				
			||||||
 | 
					    //    + QDateTime::currentDateTime().toString(Qt::ISODateWithMs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int const s = newTextLines.size();
 | 
				
			||||||
 | 
					    if (s > 0) {
 | 
				
			||||||
 | 
					        QString editText = ui->updateStatus->toPlainText();
 | 
				
			||||||
 | 
					        QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);
 | 
				
			||||||
 | 
					        QString newText;
 | 
				
			||||||
 | 
					        if (lines.size() >= s) {
 | 
				
			||||||
 | 
					            for (int i = 0; i < s; ++i) {
 | 
				
			||||||
 | 
					                lines.removeLast();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (lines.size() > 0) {
 | 
				
			||||||
 | 
					                newText = lines.join('\n');
 | 
				
			||||||
 | 
					                newText += '\n';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            QStringList newLines;
 | 
				
			||||||
 | 
					            for (int i = 0; i < s; ++i) {
 | 
				
			||||||
 | 
					                if (i == 0 && !suffix.isNull() && suffix.size() > 0 && suffix != "\n") {
 | 
				
			||||||
 | 
					                    newLines += Utils::rstrip(newTextLines.at(i).leftJustified(m_width-10) + suffix);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    newLines += Utils::rstrip(newTextLines.at(i).leftJustified(m_width-10));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            lines += newLines;
 | 
				
			||||||
 | 
					            newText += newLines.join(' ');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ui->updateStatus->setText(newText);
 | 
				
			||||||
 | 
					        Utils::printLineEditInfo(lines);
 | 
				
			||||||
 | 
					        scrollDownTextEdit();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onReplaceLast(QString text, QString suffix) {
 | 
					void MainWindow::onReplaceLast(QString text, QString suffix) {
 | 
				
			||||||
        qInfo() << "REPL TEXT" << text << "SUFFIX" << suffix;
 | 
					    // 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');
 | 
					    QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts);
 | 
				
			||||||
    if (lines.size() > 0) {
 | 
					    if (lines.size() > 0) {
 | 
				
			||||||
        lines.removeLast();
 | 
					        lines.removeLast();
 | 
				
			||||||
        if (!suffix.isNull() && suffix.size() > 0 && suffix != "\n") {
 | 
					        if (!suffix.isNull() && suffix.size() > 0 && suffix != "\n") {
 | 
				
			||||||
 | 
					            QString const add = text.leftJustified(m_width-10) + suffix;
 | 
				
			||||||
 | 
					            if (!add.isEmpty()) {
 | 
				
			||||||
                lines += text.leftJustified(m_width-10) + suffix;
 | 
					                lines += text.leftJustified(m_width-10) + suffix;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					            QString const add = text.leftJustified(m_width-10);
 | 
				
			||||||
 | 
					            if (!add.isEmpty()) {
 | 
				
			||||||
                lines += text.leftJustified(m_width-10);
 | 
					                lines += text.leftJustified(m_width-10);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Utils::printLineEditInfo(lines);
 | 
					    Utils::printLineEditInfo(lines);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ui->updateStatus->setText(lines.join('\n').trimmed());
 | 
					    ui->updateStatus->setText(lines.join('\n').trimmed());
 | 
				
			||||||
    ui->updateStatus->setEnabled(true);
 | 
					    scrollDownTextEdit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainWindow::onShowMessage(QString title, QString text) {
 | 
				
			||||||
 | 
					    this->statusBar()->clearMessage();
 | 
				
			||||||
 | 
					    this->statusBar()->showMessage( // timeout: 10000
 | 
				
			||||||
 | 
					        QString(title + " " + text).leftJustified(80, ' '), 10000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::onShowErrorMessage(QString title, QString text) {
 | 
					void MainWindow::onShowErrorMessage(QString title, QString text) {
 | 
				
			||||||
    text = text.leftJustified(50, ' ');
 | 
					    onShowMessage(title, text);
 | 
				
			||||||
    QMessageBox msgBox(QMessageBox::NoIcon, title,
 | 
					}
 | 
				
			||||||
                       text, QMessageBox::Ok,
 | 
					 | 
				
			||||||
                       nullptr, Qt::FramelessWindowHint);
 | 
					 | 
				
			||||||
    msgBox.setDefaultButton(QMessageBox::Ok);
 | 
					 | 
				
			||||||
    msgBox.defaultButton()->setVisible(false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QTimer *t = new QTimer(this);
 | 
					void MainWindow::onShowStatusMessage(QString title, QString text) {
 | 
				
			||||||
    connect(t, SIGNAL(timeout()), msgBox.defaultButton(), SLOT(click()));
 | 
					    onShowMessage(title, text);
 | 
				
			||||||
    t->setSingleShot(true);
 | 
					}
 | 
				
			||||||
    t->start(5 * 1000);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(msgBox.exec() == QMessageBox::Ok) {
 | 
					void MainWindow::onShowErrorMessage(QStringList lst) {
 | 
				
			||||||
      // do something
 | 
					    if (lst.size() >= 2) {
 | 
				
			||||||
    } else {
 | 
					        onShowMessage(lst.at(0), lst.at(1));
 | 
				
			||||||
      // do something else
 | 
					    }
 | 
				
			||||||
 | 
					    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), "");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								mainwindow.h
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								mainwindow.h
									
									
									
									
									
								
							@@ -3,13 +3,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <QMainWindow>
 | 
					#include <QMainWindow>
 | 
				
			||||||
#include <QTimer>
 | 
					#include <QTimer>
 | 
				
			||||||
 | 
					#include <QStatusBar>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QT_BEGIN_NAMESPACE
 | 
					QT_BEGIN_NAMESPACE
 | 
				
			||||||
namespace Ui { class MainWindow; }
 | 
					namespace Ui { class MainWindow; }
 | 
				
			||||||
QT_END_NAMESPACE
 | 
					QT_END_NAMESPACE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "worker.h"
 | 
					#include "worker.h"
 | 
				
			||||||
 | 
					#include "update.h"
 | 
				
			||||||
 | 
					#include "update_dc_event.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EMERGENCY_LEAVE_BL 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class hwinf;
 | 
				
			||||||
class MainWindow : public QMainWindow {
 | 
					class MainWindow : public QMainWindow {
 | 
				
			||||||
    Q_OBJECT
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,28 +28,50 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    static const int START_PROGRESS_LOOP = -1;
 | 
					    static const int START_PROGRESS_LOOP = -1;
 | 
				
			||||||
    static const int STOP_PROGRESS_LOOP = -2;
 | 
					    static const int STOP_PROGRESS_LOOP = -2;
 | 
				
			||||||
 | 
					    static const int BL_START_COUNT = 5;
 | 
				
			||||||
 | 
					    static const int BL_CHECK_COUNT = 5;
 | 
				
			||||||
 | 
					    static const int BL_IS_UP_COUNT = 5;
 | 
				
			||||||
 | 
					    static const int BL_STOP_COUNT = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int progressValue() const { return m_progressValue; }
 | 
					    UpdateDcEvent::UpdateStep updateStep() const { return m_updateStep; }
 | 
				
			||||||
 | 
					    void setUpdateStep(UpdateDcEvent::UpdateStep updateStep) { m_updateStep = updateStep; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
    void onAppendText(QString, QString suffix = "");
 | 
					    void onAppendText(QString, QString suffix = "");
 | 
				
			||||||
 | 
					    void onReplaceLast(QStringList, QString suffix = "");
 | 
				
			||||||
    void onReplaceLast(QString, QString suffix = "");
 | 
					    void onReplaceLast(QString, QString suffix = "");
 | 
				
			||||||
    void onShowErrorMessage(QString, QString);
 | 
					    void onShowErrorMessage(QString, QString);
 | 
				
			||||||
 | 
					    void onShowStatusMessage(QString, QString);
 | 
				
			||||||
 | 
					    void onShowErrorMessage(QStringList);
 | 
				
			||||||
 | 
					    void onShowStatusMessage(QStringList);
 | 
				
			||||||
    void onStopStartTimer();
 | 
					    void onStopStartTimer();
 | 
				
			||||||
    void onRestartExitTimer();
 | 
					    void onRestartExitTimer();
 | 
				
			||||||
    void onEnableExit();
 | 
					    void onEnableExit();
 | 
				
			||||||
    void onDisableExit();
 | 
					    void onDisableExit();
 | 
				
			||||||
 | 
					#if EMERGENCY_LEAVE_BL==1
 | 
				
			||||||
 | 
					    void emergencyLeaveBL();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signals:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if EMERGENCY_LEAVE_BL==1
 | 
				
			||||||
 | 
					    void leaveBL();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
    void onQuit();
 | 
					    void onQuit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    void scrollDownTextEdit();
 | 
				
			||||||
 | 
					    void onShowMessage(QString, QString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ui::MainWindow *ui;
 | 
					    Ui::MainWindow *ui;
 | 
				
			||||||
    Worker *m_worker;
 | 
					    Worker *m_worker;
 | 
				
			||||||
    int m_width;
 | 
					    int const m_width;
 | 
				
			||||||
    QTimer *m_startTimer;
 | 
					    QTimer *m_startTimer;
 | 
				
			||||||
    QTimer *m_exitTimer;
 | 
					    QTimer *m_exitTimer;
 | 
				
			||||||
    bool m_progressRunning;
 | 
					    bool m_progressRunning;
 | 
				
			||||||
    int m_progressValue;
 | 
					    //int m_progressValue;
 | 
				
			||||||
 | 
					    UpdateDcEvent::UpdateStep m_updateStep;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#endif // MAINWINDOW_H
 | 
					#endif // MAINWINDOW_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@
 | 
				
			|||||||
      <x>10</x>
 | 
					      <x>10</x>
 | 
				
			||||||
      <y>10</y>
 | 
					      <y>10</y>
 | 
				
			||||||
      <width>781</width>
 | 
					      <width>781</width>
 | 
				
			||||||
      <height>461</height>
 | 
					      <height>441</height>
 | 
				
			||||||
     </rect>
 | 
					     </rect>
 | 
				
			||||||
    </property>
 | 
					    </property>
 | 
				
			||||||
    <layout class="QGridLayout" name="gridLayout">
 | 
					    <layout class="QGridLayout" name="gridLayout">
 | 
				
			||||||
@@ -55,6 +55,15 @@
 | 
				
			|||||||
         <bold>true</bold>
 | 
					         <bold>true</bold>
 | 
				
			||||||
        </font>
 | 
					        </font>
 | 
				
			||||||
       </property>
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="verticalScrollBarPolicy">
 | 
				
			||||||
 | 
					        <enum>Qt::ScrollBarAsNeeded</enum>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="horizontalScrollBarPolicy">
 | 
				
			||||||
 | 
					        <enum>Qt::ScrollBarAsNeeded</enum>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="sizeAdjustPolicy">
 | 
				
			||||||
 | 
					        <enum>QAbstractScrollArea::AdjustToContents</enum>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
      </widget>
 | 
					      </widget>
 | 
				
			||||||
     </item>
 | 
					     </item>
 | 
				
			||||||
    </layout>
 | 
					    </layout>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										271
									
								
								plugins/interfaces.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										271
									
								
								plugins/interfaces.h
									
									
									
									
									
										
										
										Normal file → Executable 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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
 | 
					class hwinf
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -818,7 +852,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 +874,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 +1326,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 +1336,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 +1381,213 @@ 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ------------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					    //    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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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;
 | 
				
			||||||
@@ -1360,8 +1605,6 @@ signals:
 | 
				
			|||||||
    virtual void hwapi_payCancelled(void) const=0;
 | 
					    virtual void hwapi_payCancelled(void) const=0;
 | 
				
			||||||
    virtual void hwapi_coinProcessJustStopped(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_doorServiceDoorOpened(void) const=0;
 | 
				
			||||||
    virtual void hwapi_doorVaultDoorOpened(void) const=0;
 | 
					    virtual void hwapi_doorVaultDoorOpened(void) const=0;
 | 
				
			||||||
    virtual void hwapi_doorCoinBoxRemoved(void) const=0;
 | 
					    virtual void hwapi_doorCoinBoxRemoved(void) const=0;
 | 
				
			||||||
@@ -1413,9 +1656,23 @@ 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
 | 
				
			||||||
 | 
					//#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)
 | 
					Q_DECLARE_INTERFACE(hwinf, HWINF_iid)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								plugins/libCAmaster.so
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								plugins/libCAmaster.so
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -2,13 +2,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <QProcess>
 | 
					#include <QProcess>
 | 
				
			||||||
#include <QDebug>
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QDir>
 | 
				
			||||||
#include <QRegularExpression>
 | 
					#include <QRegularExpression>
 | 
				
			||||||
 | 
					#include <QDateTime>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Command::Command(QString const &command, int start_timeout, int finish_timeout)
 | 
					Command::Command(QString const &command, int start_timeout, int finish_timeout)
 | 
				
			||||||
    : m_command(command.trimmed())
 | 
					    : m_command(command.trimmed())
 | 
				
			||||||
    , m_commandResult("")
 | 
					    , m_commandResult("")
 | 
				
			||||||
    , m_waitForStartTimeout(start_timeout)
 | 
					    , m_waitForStartTimeout(start_timeout)
 | 
				
			||||||
    , m_waitForFinishTimeout(finish_timeout) {
 | 
					    , m_waitForFinishTimeout(finish_timeout)
 | 
				
			||||||
 | 
					    , m_exitCode(-1) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString Command::getCommandResult() const {
 | 
					QString Command::getCommandResult() const {
 | 
				
			||||||
@@ -39,46 +42,83 @@ void Command::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Command::execute(QString workingDirectory, QStringList args) {
 | 
					bool Command::execute(QString workingDirectory, QStringList args) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!QDir::setCurrent(workingDirectory)) {
 | 
				
			||||||
 | 
					        qCritical() << "SET WORKING_DIRECTORY" << workingDirectory
 | 
				
			||||||
 | 
					                    << "FAILED FOR" << m_command;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QScopedPointer<QProcess> p(new QProcess(this));
 | 
					    QScopedPointer<QProcess> p(new QProcess(this));
 | 
				
			||||||
 | 
					    p->setWorkingDirectory(workingDirectory);
 | 
				
			||||||
    p->setProcessChannelMode(QProcess::MergedChannels);
 | 
					    p->setProcessChannelMode(QProcess::MergedChannels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
 | 
					    connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
 | 
				
			||||||
    connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
 | 
					    connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //qCritical() << "START COMMAND" << m_command << "WITH ARGS" << args
 | 
					 | 
				
			||||||
    //            << "IN" << workingDirectory;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    p->setWorkingDirectory(workingDirectory);
 | 
					 | 
				
			||||||
    if (!args.isEmpty()) {
 | 
					    if (!args.isEmpty()) {
 | 
				
			||||||
 | 
					        qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args
 | 
				
			||||||
 | 
					                 << "IN" << p->workingDirectory();
 | 
				
			||||||
        p->start(m_command, args);
 | 
					        p->start(m_command, args);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					        qDebug() << "START COMMAND" << m_command
 | 
				
			||||||
 | 
					                 << "IN" << p->workingDirectory();
 | 
				
			||||||
        p->start(m_command);
 | 
					        p->start(m_command);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (p->waitForStarted(m_waitForStartTimeout)) {
 | 
					    if (p->waitForStarted(m_waitForStartTimeout)) {
 | 
				
			||||||
        //qDebug() << "PROCESS" << m_command << "STARTED";
 | 
					        qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory();
 | 
				
			||||||
        if (p->state() == QProcess::ProcessState::Running) {
 | 
					        if (p->state() == QProcess::ProcessState::Running) {
 | 
				
			||||||
            //qDebug() << "PROCESS" << m_command << "RUNNING";
 | 
					            qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory();
 | 
				
			||||||
            if (p->waitForFinished(m_waitForFinishTimeout)) {
 | 
					            // wait forever for git/opkg-commands to finish
 | 
				
			||||||
                //qDebug() << "PROCESS" << m_command << "FINISHED";
 | 
					            int wait = m_waitForFinishTimeout;
 | 
				
			||||||
 | 
					            if (m_command.trimmed().startsWith("git", Qt::CaseInsensitive) ||
 | 
				
			||||||
 | 
					                m_command.trimmed().startsWith("opkg", Qt::CaseInsensitive)) {
 | 
				
			||||||
 | 
					                wait = -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            bool const no_timeout = p->waitForFinished(wait);
 | 
				
			||||||
 | 
					            if (no_timeout) {
 | 
				
			||||||
 | 
					                qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory();
 | 
				
			||||||
                if (p->exitStatus() == QProcess::NormalExit) {
 | 
					                if (p->exitStatus() == QProcess::NormalExit) {
 | 
				
			||||||
                    if (p->exitCode() == 0) {
 | 
					                    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;
 | 
					                        return true;
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        qCritical() << "EXECUTED" << m_command << "with code" << p->exitCode();
 | 
					                        qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
				
			||||||
 | 
					                        qCritical() << "EXECUTED" << m_command
 | 
				
			||||||
 | 
					                                    << QString("(runtime %1ms)").arg(end-start)
 | 
				
			||||||
 | 
					                                    << "with code" << m_exitCode
 | 
				
			||||||
 | 
					                                    << "IN" << p->workingDirectory();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
 | 
					                    qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
				
			||||||
                    qCritical() << "PROCESS" << m_command << "CRASHED with code"
 | 
					                    qCritical() << "PROCESS" << m_command << "CRASHED with code"
 | 
				
			||||||
                                << p->exitCode();
 | 
					                                << p->exitCode()
 | 
				
			||||||
 | 
					                                << QString("(after %1ms)").arg(end-start)
 | 
				
			||||||
 | 
					                                << "IN" << p->workingDirectory();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                qCritical() << "PROCESS" << m_command << "DID NOT FINISH";
 | 
					                qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
				
			||||||
 | 
					                qCritical() << "PROCESS" << m_command
 | 
				
			||||||
 | 
					                            << "DID NOT FINISH WITH" << wait
 | 
				
			||||||
 | 
					                            << "MS IN" << p->workingDirectory()
 | 
				
			||||||
 | 
					                            << QString("(runtime %1ms)").arg(end-start);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            qCritical() << "WRONG PROCESS STATE" << p->state();
 | 
					            qCritical() << "WRONG PROCESS STATE" << p->state()
 | 
				
			||||||
 | 
					                        << "IN" << p->workingDirectory();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        qCritical() << "PROCESS" << m_command << "TIMEOUT AT START";
 | 
					        qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch();
 | 
				
			||||||
 | 
					        qCritical() << "PROCESS" << m_command << "TIMEOUT AT START"
 | 
				
			||||||
 | 
					                    << QString("(runtime %1ms)").arg(end-start)
 | 
				
			||||||
 | 
					                    << "IN" << p->workingDirectory();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,15 +16,17 @@ class Command : public QObject {
 | 
				
			|||||||
    QString m_commandResult;
 | 
					    QString m_commandResult;
 | 
				
			||||||
    int m_waitForStartTimeout;
 | 
					    int m_waitForStartTimeout;
 | 
				
			||||||
    int m_waitForFinishTimeout;
 | 
					    int m_waitForFinishTimeout;
 | 
				
			||||||
 | 
					    int m_exitCode;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    explicit Command(QString const &command,
 | 
					    explicit Command(QString const &command,
 | 
				
			||||||
                     int start_timeout = 100000,
 | 
					                     int start_timeout = 100000,
 | 
				
			||||||
                     int finish_timeout = 100000);
 | 
					                     int finish_timeout = 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QString getCommandResult() const;
 | 
					    QString getCommandResult() const;
 | 
				
			||||||
 | 
					    QString command() const { return m_command; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool execute(QString workingDirectory, QStringList args = QStringList());
 | 
					    bool execute(QString workingDirectory, QStringList args = QStringList());
 | 
				
			||||||
 | 
					    int exitCode() const { return m_exitCode; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
    void readyReadStandardOutput();
 | 
					    void readyReadStandardOutput();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										489
									
								
								update.cpp
									
									
									
									
									
								
							
							
						
						
									
										489
									
								
								update.cpp
									
									
									
									
									
								
							@@ -1,5 +1,8 @@
 | 
				
			|||||||
#include "update.h"
 | 
					#include "update.h"
 | 
				
			||||||
#include "worker.h"
 | 
					#include "worker.h"
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					#include "update_dc_event.h"
 | 
				
			||||||
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QCoreApplication>
 | 
					#include <QCoreApplication>
 | 
				
			||||||
#include <QApplication>
 | 
					#include <QApplication>
 | 
				
			||||||
@@ -9,10 +12,11 @@
 | 
				
			|||||||
#include <QTextStream>
 | 
					#include <QTextStream>
 | 
				
			||||||
#include <QRegularExpression>
 | 
					#include <QRegularExpression>
 | 
				
			||||||
#include <QRegExp>
 | 
					#include <QRegExp>
 | 
				
			||||||
 | 
					#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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,17 +29,15 @@
 | 
				
			|||||||
#include <QMap>
 | 
					#include <QMap>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UPDATE_OPKG                 (1)
 | 
					#define UPDATE_OPKG                 (1)
 | 
				
			||||||
#define UPDATE_DC                   (1)
 | 
					#define UPDATE_DC                   (0)
 | 
				
			||||||
#define UPDATE_PRINTER_TEMPLATES    (1)
 | 
					 | 
				
			||||||
#define UPDATE_CASH_TEMPLATE        (1)
 | 
					 | 
				
			||||||
#define UPDATE_CONF_TEMPLATE        (1)
 | 
					 | 
				
			||||||
#define UPDATE_DEVICE_TEMPLATE      (1)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const QMap<QString, int> baudrateMap = {
 | 
					static const QMap<QString, int> baudrateMap = {
 | 
				
			||||||
  {"1200"   ,   0}, {"9600"   ,   1}, {"19200"  ,   2}, {"38400"  ,   3},
 | 
					  {"1200"   ,   0}, {"9600"   ,   1}, {"19200"  ,   2}, {"38400"  ,   3},
 | 
				
			||||||
  {"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()) {
 | 
				
			||||||
@@ -44,7 +46,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();
 | 
				
			||||||
@@ -76,26 +79,51 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
 | 
				
			|||||||
    return hw;
 | 
					    return hw;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Update::Update(hwinf *hw,
 | 
					bool Update::unloadDCPlugin() {
 | 
				
			||||||
               Worker *worker,
 | 
					    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(Worker *worker,
 | 
				
			||||||
               QString customerRepository,
 | 
					               QString customerRepository,
 | 
				
			||||||
               QString customerNrStr,
 | 
					               QString customerNrStr,
 | 
				
			||||||
               QString branchName,
 | 
					               QString branchName,
 | 
				
			||||||
 | 
					               QString plugInDir,
 | 
				
			||||||
 | 
					               QString pluginName,
 | 
				
			||||||
               QString workingDir,
 | 
					               QString workingDir,
 | 
				
			||||||
               bool dryRun,
 | 
					               bool dryRun,
 | 
				
			||||||
               QObject *parent,
 | 
					               QObject *parent,
 | 
				
			||||||
               char const *serialInterface,
 | 
					               char const *serialInterface,
 | 
				
			||||||
               char const *baudrate)
 | 
					               char const *baudrate)
 | 
				
			||||||
    : QObject(parent)
 | 
					    : QObject(parent)
 | 
				
			||||||
    , m_hw(hw)
 | 
					    , m_hw(loadDCPlugin(QDir(plugInDir), pluginName))
 | 
				
			||||||
    , m_worker(worker)
 | 
					    , m_worker(worker)
 | 
				
			||||||
    , m_serialInterface(serialInterface)
 | 
					    , m_serialInterface(serialInterface)
 | 
				
			||||||
    , m_baudrate(baudrate)
 | 
					    , m_baudrate(baudrate)
 | 
				
			||||||
    , m_customerRepository(customerRepository)
 | 
					    , m_customerRepository(customerRepository)
 | 
				
			||||||
    , m_customerNrStr(customerNrStr)
 | 
					    , m_customerNrStr(customerNrStr)
 | 
				
			||||||
    , m_branchName(branchName)
 | 
					    , m_branchName(branchName)
 | 
				
			||||||
 | 
					    , m_pluginName(pluginName)
 | 
				
			||||||
    , m_workingDir(workingDir)
 | 
					    , m_workingDir(workingDir)
 | 
				
			||||||
    , m_dryRun(dryRun) {
 | 
					    , m_dryRun(dryRun) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_serialInterface    ..." << m_serialInterface;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_baudrate           ..." << m_baudrate;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_customerRepository ..." << m_customerRepository;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_customerNr ..........." << m_customerNrStr;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_branchName ..........." << m_branchName;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_pluginName ..........." << m_pluginName;
 | 
				
			||||||
 | 
					    qInfo() << "UPDATE: m_workingDirectory ....." << m_workingDir;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Update::~Update() {
 | 
					Update::~Update() {
 | 
				
			||||||
@@ -221,48 +249,99 @@ Update::DownloadResult Update::dc_downloadBinary(QByteArray const &b) const {
 | 
				
			|||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Update::startBootloader() const {
 | 
					bool Update::startBootloader() const { // deprecated
 | 
				
			||||||
    qDebug() << "starting bootloader...";
 | 
					    return false;
 | 
				
			||||||
    int nTry = 5;
 | 
					#if 0
 | 
				
			||||||
    while (--nTry >= 0) {
 | 
					    int nStartTry = 5;
 | 
				
			||||||
 | 
					    while (--nStartTry >= 0) {
 | 
				
			||||||
        m_hw->bl_startBL();
 | 
					        m_hw->bl_startBL();
 | 
				
			||||||
        QThread::msleep(5000);
 | 
					        QThread::msleep(500);
 | 
				
			||||||
 | 
					        int nCheckTry = 10;
 | 
				
			||||||
 | 
					        while (--nCheckTry >= 0) {
 | 
				
			||||||
            m_hw->bl_checkBL();
 | 
					            m_hw->bl_checkBL();
 | 
				
			||||||
 | 
					            QThread::msleep(500);
 | 
				
			||||||
            if (m_hw->bl_isUp()) {
 | 
					            if (m_hw->bl_isUp()) {
 | 
				
			||||||
                qInfo() << "starting bootloader...OK";
 | 
					                qInfo() << "starting bootloader...OK";
 | 
				
			||||||
            QThread::msleep(5000);
 | 
					 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
            qCritical() << "bootloader not up (" << nTry << ")";
 | 
					                qCritical() << "bootloader not up ("
 | 
				
			||||||
 | 
					                            << nStartTry << "," << nCheckTry << ")" << QThread::currentThread();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    qCritical() << "starting bootloader...FAILED";
 | 
					    }
 | 
				
			||||||
 | 
					    qCritical() << "starting bootloader...FAILED" << QThread::currentThread();
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Update::stopBootloader() const {
 | 
					bool Update::stopBootloader() const {
 | 
				
			||||||
    qDebug() << "stopping bootloader...";
 | 
					    // stop bootloader: this MUST work -> otherwise the PSA has to be restarted
 | 
				
			||||||
    int nTry = 5;
 | 
					    // manually
 | 
				
			||||||
    while (--nTry >= 0) {
 | 
					    emit m_worker->showErrorMessage("dc update", "stopping bootloader...");
 | 
				
			||||||
        m_hw->bl_stopBL();
 | 
					
 | 
				
			||||||
 | 
					    int nTryFinalize = 1; // could do this in an endless loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        // in principle, any value except BL_STOP will do, as we want to detect
 | 
				
			||||||
 | 
					        // change to BL_STOP
 | 
				
			||||||
 | 
					        m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::BL_CHECK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QApplication::postEvent(
 | 
				
			||||||
 | 
					            m_worker->mainWindow(),
 | 
				
			||||||
 | 
					            new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_STOP, nTryFinalize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int const cntLimit = 20;
 | 
				
			||||||
 | 
					        int cnt = 0;
 | 
				
			||||||
 | 
					        while (++cnt < cntLimit &&
 | 
				
			||||||
 | 
					            m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_STOP) {
 | 
				
			||||||
 | 
					            // wait until bl_stopBL() has been sent
 | 
				
			||||||
            QThread::msleep(500);
 | 
					            QThread::msleep(500);
 | 
				
			||||||
        if (!m_hw->bl_isUp()) {
 | 
					 | 
				
			||||||
            qInfo() << "stopping bootloader...OK";
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QApplication::postEvent(
 | 
				
			||||||
 | 
					            m_worker->mainWindow(),
 | 
				
			||||||
 | 
					            new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_CHECK, nTryFinalize));
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        QApplication::postEvent(
 | 
				
			||||||
 | 
					            m_worker->mainWindow(),
 | 
				
			||||||
 | 
					            new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_IS_UP, nTryFinalize));
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cnt = 0;
 | 
				
			||||||
 | 
					        while (++cnt < cntLimit &&
 | 
				
			||||||
 | 
					            m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_DOWN) {
 | 
				
			||||||
 | 
					            // wait until  done
 | 
				
			||||||
 | 
					            QThread::msleep(200);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    qCritical() << "stopping bootloader...FAILED";
 | 
					
 | 
				
			||||||
    return false;
 | 
					    } while (++nTryFinalize <= MainWindow::BL_STOP_COUNT &&
 | 
				
			||||||
 | 
					             m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_DOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_DOWN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// br is a index into a table, used for historical reasons.
 | 
					// br is a index into a table, used for historical reasons.
 | 
				
			||||||
bool Update::openSerial(int br, QString baudrate, QString comPort) const {
 | 
					bool Update::openSerial(int br, QString baudrate, QString comPort) const {
 | 
				
			||||||
    qDebug() << "opening serial" << br << baudrate << comPort << "...";
 | 
					    qDebug() << "opening serial" << br << baudrate << comPort << "...";
 | 
				
			||||||
    if (m_hw->dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect
 | 
					    if (m_hw->dc_openSerial(br, baudrate, comPort, 1) == true) { // 1 for connect
 | 
				
			||||||
        qInfo() << "opening serial" << br << baudrate << comPort << "...OK";
 | 
					        Utils::printInfoMsg(
 | 
				
			||||||
 | 
					            QString("OPENING SERIAL %1").arg(br)
 | 
				
			||||||
 | 
					                  + " " + baudrate + " " + comPort + "...OK");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // m_hw->dc_autoRequest(true);
 | 
				
			||||||
 | 
					        m_hw->dc_autoRequest(false);
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Utils::printInfoMsg(QString("IS PORT OPEN %1").arg(m_hw->dc_isPortOpen()));
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED";
 | 
					
 | 
				
			||||||
 | 
					    Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					        QString("OPENING SERIAL %1").arg(br)
 | 
				
			||||||
 | 
					              + " " + baudrate + " " + comPort + "...FAILED");
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -275,13 +354,15 @@ bool Update::isSerialOpen() const {
 | 
				
			|||||||
    return m_hw->dc_isPortOpen();
 | 
					    return m_hw->dc_isPortOpen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Update::resetDeviceController() const {
 | 
					bool Update::resetDeviceController() const { // deprecated
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
    qDebug() << "resetting device controller...";
 | 
					    qDebug() << "resetting device controller...";
 | 
				
			||||||
    m_hw->bl_rebootDC();
 | 
					    m_hw->bl_rebootDC();
 | 
				
			||||||
    // wait maximally 3 seconds, before starting bootloader
 | 
					    // wait maximally 3 seconds, before starting bootloader
 | 
				
			||||||
    QThread::sleep(1);
 | 
					 | 
				
			||||||
    qInfo() << "resetting device controller...OK";
 | 
					    qInfo() << "resetting device controller...OK";
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QByteArray Update::loadBinaryDCFile(QString filename) const {
 | 
					QByteArray Update::loadBinaryDCFile(QString filename) const {
 | 
				
			||||||
@@ -319,17 +400,61 @@ bool Update::downloadBinaryToDC(QString const &bFile) const {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 Using the DC bootloader:
 | 
					 | 
				
			||||||
 1  :   bl_reboot()      // send to application, want DC2 to reset (in order to start
 | 
					 | 
				
			||||||
                        // the bootloader)
 | 
					 | 
				
			||||||
 2  :   bl_startBL():   // send within 4s after DC poewer-on, otherwise bl is left
 | 
					 | 
				
			||||||
 3  :   bl_check():     // send command to verify if bl is up
 | 
					 | 
				
			||||||
 4  :   bl_isUp():      // returns true if bl is up and running
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					 //
 | 
				
			||||||
 | 
					 //                        USING THE DC BOOTLOADER
 | 
				
			||||||
 | 
					 //
 | 
				
			||||||
 | 
					 ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 1  :   bl_reboot()     // send to application, want DC2 to reset (in order to
 | 
				
			||||||
 | 
					                        // start the bootloader)
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: this function is NOT reliable !!! Sometimes it
 | 
				
			||||||
 | 
					                        // simply does not work, in which case bl_startBL,
 | 
				
			||||||
 | 
					                        // bl_checkBL and bl_isUp do not work as well.
 | 
				
			||||||
 | 
					                        // Alas, there is no feedback if bl_reboot worked!
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: this function can be called only once per
 | 
				
			||||||
 | 
					                        // minute, because once called again, the controller
 | 
				
			||||||
 | 
					                        // performs some self-checks consuming some time.
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: after a successful bl_reboot(), the device is
 | 
				
			||||||
 | 
					                        // waiting about 4 seconds in the bootloader. To stay in
 | 
				
			||||||
 | 
					                        // the bootloader, we have to send the command
 | 
				
			||||||
 | 
					                        // bl_startBL(), which is kind of a misnomer, as it
 | 
				
			||||||
 | 
					                        // should be bl_doNotLeaveBL().
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					 2  :   bl_startBL():   // send within 4s after DC power-on, otherwise
 | 
				
			||||||
 | 
					                        // bootloader is left.
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: a running bootloader is a MUST for the download
 | 
				
			||||||
 | 
					                        // process of a device controller firmware as it does
 | 
				
			||||||
 | 
					                        // the actual writing of the memory (the bl_reboot()
 | 
				
			||||||
 | 
					                        // from above erases the available memory).
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					 3  :   bl_check():     // send command to verify if bl is up
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: this command is kind of a request that we want
 | 
				
			||||||
 | 
					                        // to check if the bootloader is up. The device
 | 
				
			||||||
 | 
					                        // (actually the bootloader) responds with its version.
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					 4  :   bl_isUp():      // returns true if bl is up and running
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: we know what the bootloader version actually is
 | 
				
			||||||
 | 
					                        // as the bootloader does not change. By comparing the
 | 
				
			||||||
 | 
					                        // string received in the previous step with this known
 | 
				
			||||||
 | 
					                        // version string we know if the bootloader is up.
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE FOR ALL PREVIOUS STEPS: execute them in their
 | 
				
			||||||
 | 
					                        // own slots each to be sure to receive any possible
 | 
				
			||||||
 | 
					                        // responds from the device.
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 5  :   bl_sendAddress(blockNumber)
 | 
					 5  :   bl_sendAddress(blockNumber)
 | 
				
			||||||
                        // send start address, nr of 64-byte block, start with 0
 | 
					                        // send start address, nr of 64-byte block, start with 0
 | 
				
			||||||
                        // will be sent only for following block-numbers:
 | 
					                        // will be sent only for following block-numbers:
 | 
				
			||||||
                        // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
 | 
					                        // 0, 1024, 2048, 3072 and 4096, so basically every
 | 
				
			||||||
 | 
					                        // 64kByte.
 | 
				
			||||||
                        // for other addresses nothing happens
 | 
					                        // for other addresses nothing happens
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 6  :   bl_wasSendingAddOK()
 | 
					 6  :   bl_wasSendingAddOK()
 | 
				
			||||||
@@ -349,54 +474,119 @@ bool Update::downloadBinaryToDC(QString const &bFile) const {
 | 
				
			|||||||
                        //             10: OK
 | 
					                        //             10: OK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 10 :   bl_stopBL()     // leave bl and start (the new) application
 | 
					 10 :   bl_stopBL()     // leave bl and start (the new) application
 | 
				
			||||||
 | 
					                        //
 | 
				
			||||||
 | 
					                        // NOTE: this function MUST work under all conditions.
 | 
				
			||||||
 | 
					                        // Alas, there is no direct result for this command, so
 | 
				
			||||||
 | 
					                        // the only way of knowing it was successful is to ask
 | 
				
			||||||
 | 
					                        // the device if the bootloader is still running.
 | 
				
			||||||
 | 
					                        // There is no problem to repeat this command until the
 | 
				
			||||||
 | 
					                        // bootloader is really not running anymore.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool Update::updateBinary(char const *fileToSendToDC) {
 | 
					bool Update::updateBinary(char const *fileToSendToDC) {
 | 
				
			||||||
    qInfo() << "UPDATING DEVICE CONTROLLER BINARY" << fileToSendToDC;
 | 
					    qInfo() << "UPDATING DEVICE CONTROLLER FIRMWARE BINARY" << fileToSendToDC;
 | 
				
			||||||
    QFile fn(fileToSendToDC);
 | 
					    QFile fn(fileToSendToDC);
 | 
				
			||||||
    bool r;
 | 
					    bool r;
 | 
				
			||||||
    if ((r = fn.exists()) == true) {
 | 
					    if ((r = fn.exists()) == true) {
 | 
				
			||||||
        QFileInfo fi(fn);
 | 
					        QFileInfo fi(fn);
 | 
				
			||||||
        qInfo() << "      UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ")";
 | 
					 | 
				
			||||||
        if ((r = updateDC(fileToSendToDC)) == true) {
 | 
					        if ((r = updateDC(fileToSendToDC)) == true) {
 | 
				
			||||||
            qCritical() << QString(80, '*');
 | 
					            Utils::printInfoMsg(
 | 
				
			||||||
            qInfo() << "      UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ") DONE";
 | 
					                QString("      UPDATING BINARY ") + fi.fileName()
 | 
				
			||||||
            qCritical() << QString(80, '*');
 | 
					                      + QString(" (size=%1").arg(fi.size()) + ") DONE");
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            qCritical() << QString(80, '*');
 | 
					            Utils::printCriticalErrorMsg(
 | 
				
			||||||
            qCritical() << "      UPDATING BINARY" << fi.fileName() << "(size=" << fi.size() << ") FAILED";
 | 
					                QString("      UPDATING BINARY ") + fi.fileName()
 | 
				
			||||||
            qCritical() << QString(80, '*');
 | 
					                      + QString(" (size=%1").arg(fi.size()) + ") FAILED");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        qCritical() << QString(80, '*');
 | 
					        Utils::printCriticalErrorMsg(
 | 
				
			||||||
        qCritical() << fileToSendToDC << "does not exist -> NO UPDATE OF DC FIRMWARE";
 | 
					            QString(fileToSendToDC) + " DOES NOT EXIST -> NO UPDATE OF DC FIRMWARE");
 | 
				
			||||||
        qCritical() << QString(80, '*');
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return r;
 | 
					    return r;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Update::updateDC(QString bFile) const {
 | 
					bool Update::updateDC(QString bFile) const {
 | 
				
			||||||
    qDebug() << "updating dc...";
 | 
					    qDebug() << "IN UPDATEDC: UPDATING DC: FILE TO SEND" << bFile;
 | 
				
			||||||
    qDebug() << "updating dc: file to send" << bFile;
 | 
					
 | 
				
			||||||
    if (!resetDeviceController()) {
 | 
					    m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::NONE);
 | 
				
			||||||
        return false;
 | 
					
 | 
				
			||||||
 | 
					    QApplication::postEvent(            // step 1: reset device controller
 | 
				
			||||||
 | 
					        m_worker->mainWindow(),
 | 
				
			||||||
 | 
					        new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::DC_REBOOT, 1));
 | 
				
			||||||
 | 
					    QThread::sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i=1; i <= MainWindow::BL_START_COUNT; ++i) {
 | 
				
			||||||
 | 
					        QApplication::postEvent(        // step 2: start bootloader (5x)
 | 
				
			||||||
 | 
					            m_worker->mainWindow(),
 | 
				
			||||||
 | 
					            new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_START, i));
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!startBootloader()) {
 | 
					
 | 
				
			||||||
        // even when start seems to fail, stopping the boot loader does not harm
 | 
					    int const cntLimit = 100;       // wait until its for sure that bl_startBL()
 | 
				
			||||||
        stopBootloader();
 | 
					    int cnt = 0;                    // has been excuted
 | 
				
			||||||
 | 
					    while (++cnt < cntLimit &&
 | 
				
			||||||
 | 
					        m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_START) {
 | 
				
			||||||
 | 
					        // wait until all bl_startBL() are done
 | 
				
			||||||
 | 
					        QThread::msleep(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cnt == cntLimit) {
 | 
				
			||||||
 | 
					        // start events not received ???
 | 
				
			||||||
 | 
					        Utils::printCriticalErrorMsg("BL_START EVENT NOT RECEIVED AFTER 20 SECS");
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_worker->mainWindow()->setUpdateStep(UpdateDcEvent::UpdateStep::BL_CHECK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i=1; i <= MainWindow::BL_IS_UP_COUNT; ++i) {
 | 
				
			||||||
 | 
					        QApplication::postEvent(m_worker->mainWindow(), new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_CHECK, i));
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					        QApplication::postEvent(m_worker->mainWindow(), new UpdateDcEvent(m_worker, UpdateDcEvent::UpdateStep::BL_IS_UP, i));
 | 
				
			||||||
 | 
					        if (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_UP) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        QThread::sleep(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cnt = 0;
 | 
				
			||||||
 | 
					    while (++cnt < cntLimit &&
 | 
				
			||||||
 | 
					        m_worker->mainWindow()->updateStep() != UpdateDcEvent::UpdateStep::BL_IS_UP) {
 | 
				
			||||||
 | 
					        // wait until all bl_startBL() are done
 | 
				
			||||||
 | 
					        QThread::msleep(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cnt == cntLimit) {
 | 
				
			||||||
 | 
					        // really not up
 | 
				
			||||||
 | 
					        Utils::printCriticalErrorMsg("BL_IS_UP EVENT NOT RECEIVED AFTER 20 SECS");
 | 
				
			||||||
 | 
					        stopBootloader(); // try to stop bootloader whichhas been already started
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (m_worker->mainWindow()->updateStep() == UpdateDcEvent::UpdateStep::BL_IS_UP) {
 | 
				
			||||||
 | 
					        // bootloader MUST be running to download device-controller
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
        if (!downloadBinaryToDC(bFile)) {
 | 
					        if (!downloadBinaryToDC(bFile)) {
 | 
				
			||||||
        stopBootloader();
 | 
					            Utils::printCriticalErrorMsg(
 | 
				
			||||||
        qCritical() << "updating dc: " << bFile << "...FAILED";
 | 
					                QString("UPDATING DC: ") + bFile + " ...DOWNLOAD FAILED");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					            QString("UPDATING DC: ") + bFile + " BOOT LOADER NOT RUNNING -> NO DOWNLOAD ("
 | 
				
			||||||
 | 
					                  + QThread::currentThread()->objectName() + ")");
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    qInfo() << "updating dc: " << bFile << "...OK";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stopBootloader();
 | 
					    // do this unconditionally, even if bootloader is not running at all ->
 | 
				
			||||||
    //resetDeviceController();
 | 
					    // the controller possibly tells us nonsense.
 | 
				
			||||||
 | 
					    if (!stopBootloader()) {
 | 
				
			||||||
 | 
					        Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					            QString("UPDATING DC: ") + bFile + " BOOT LOADER STILL RUNNING ("
 | 
				
			||||||
 | 
					                  + QThread::currentThread()->objectName() + ")");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QThread::sleep(3);
 | 
					    Utils::printInfoMsg(QString("UPDATING DC: ") + bFile + " ...OK");
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -416,9 +606,12 @@ bool Update::downloadJson(enum FileTypeJson type,
 | 
				
			|||||||
                          int templateIdx,
 | 
					                          int templateIdx,
 | 
				
			||||||
                          QString jsFileToSendToDC) const {
 | 
					                          QString jsFileToSendToDC) const {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qDebug() << "updating json-file:" << jsFileToSendToDC << "...";
 | 
					
 | 
				
			||||||
    qDebug() << "    template-index:" << templateIdx;
 | 
					    Utils::printInfoMsg(
 | 
				
			||||||
    qDebug() << "         json-type:" << jsonType(type);
 | 
					        QString("UPDATING JSON-FILE=%1, TEMPLATE-INDEX=%2, JSON-TYPE=%3")
 | 
				
			||||||
 | 
					            .arg(jsFileToSendToDC)
 | 
				
			||||||
 | 
					            .arg(templateIdx)
 | 
				
			||||||
 | 
					            .arg(jsonType(type)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag
 | 
					    m_hw->dc_autoRequest(true); // downloading Json needs the AutoEmission flag
 | 
				
			||||||
    qDebug() << "SET AUTO-REQUEST=TRUE";
 | 
					    qDebug() << "SET AUTO-REQUEST=TRUE";
 | 
				
			||||||
@@ -429,7 +622,7 @@ bool Update::downloadJson(enum FileTypeJson type,
 | 
				
			|||||||
    while ((ready = m_hw->sys_ready4sending()) == false) {
 | 
					    while ((ready = m_hw->sys_ready4sending()) == false) {
 | 
				
			||||||
        QThread::msleep(200);
 | 
					        QThread::msleep(200);
 | 
				
			||||||
        if (--nTry <= 0) {
 | 
					        if (--nTry <= 0) {
 | 
				
			||||||
            qCritical() << "SYS NOT READY FOR SENDING AFTER 5 SECONDS";
 | 
					            Utils::printCriticalErrorMsg("SYS NOT READY FOR SENDING AFTER 5 SECONDS");
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -442,22 +635,27 @@ bool Update::downloadJson(enum FileTypeJson type,
 | 
				
			|||||||
            if (file.open(QIODevice::ReadOnly)) {
 | 
					            if (file.open(QIODevice::ReadOnly)) {
 | 
				
			||||||
                if (fi.size() <= 800) {
 | 
					                if (fi.size() <= 800) {
 | 
				
			||||||
                    QByteArray ba = file.readAll();
 | 
					                    QByteArray ba = file.readAll();
 | 
				
			||||||
 | 
					                    // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
 | 
				
			||||||
 | 
					                    //      nrOfTemplate=1...32 if kindOfFile==6
 | 
				
			||||||
 | 
					                    //      content = content of the Json file, max 800byte ascii signs
 | 
				
			||||||
                    if (m_hw->sys_sendJsonFileToDc((uint8_t)(type),
 | 
					                    if (m_hw->sys_sendJsonFileToDc((uint8_t)(type),
 | 
				
			||||||
                                                   templateIdx,
 | 
					                                                   templateIdx,
 | 
				
			||||||
                                                   (uint8_t *)ba.data())) {
 | 
					                                                   (uint8_t *)ba.data())) {
 | 
				
			||||||
                        QThread::sleep(1);
 | 
					                        QThread::sleep(1);
 | 
				
			||||||
                        qDebug() << "SENT" << jsFileToSendToDC;
 | 
					 | 
				
			||||||
                        ret = true;
 | 
					                        ret = true;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    qCritical() << "SIZE OF" << jsFileToSendToDC
 | 
					                    Utils::printCriticalErrorMsg(
 | 
				
			||||||
                                << "TOO BIG (" << fi.size() << "BYTES)";
 | 
					                        QString("SIZE OF %1 TOO BIG (%2 BYTES)")
 | 
				
			||||||
 | 
					                            .arg(jsFileToSendToDC).arg(fi.size()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                qCritical() << "CANNOT OPEN" << jsFileToSendToDC << "FOR READING";
 | 
					                Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					                    QString("CAN NOT OPEN ") + jsFileToSendToDC + " FOR READING");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            qCritical() << jsFileToSendToDC << "DOES NOT EXIST";
 | 
					            Utils::printCriticalErrorMsg(
 | 
				
			||||||
 | 
					                QString(jsFileToSendToDC) + " DOES NOT EXIST");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -518,40 +716,9 @@ void Update::finished(int /*exitCode*/, QProcess::ExitStatus /*exitStatus*/) {
 | 
				
			|||||||
    disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
 | 
					    disconnect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(readyReadStandardError()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
					QStringList Update::getDcSoftAndHardWareVersion() {
 | 
				
			||||||
    //
 | 
					    m_hw->dc_autoRequest(true);
 | 
				
			||||||
    // ACHTUNG !!!
 | 
					    QThread::sleep(1); // make sure the timer-slots are active
 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool serialOpened = false;
 | 
					 | 
				
			||||||
    bool serialOpen = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!serialOpen) {
 | 
					 | 
				
			||||||
        if (!isSerialOpen()) { // open serial only if not already open
 | 
					 | 
				
			||||||
            if ((serialOpened = openSerial(baudrateMap.value(m_baudrate), m_baudrate, m_serialInterface)) == false) {
 | 
					 | 
				
			||||||
                qCritical() << "CANNOT OPEN" << m_serialInterface << "(BAUDRATE="
 | 
					 | 
				
			||||||
                            << m_baudrate << ")";
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        serialOpen = true;
 | 
					 | 
				
			||||||
        qInfo() << "SERIAL OPEN" << m_serialInterface << "(BAUDRATE=" << m_baudrate << ")";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool res = false;
 | 
					 | 
				
			||||||
    QList<QString>::const_iterator it;
 | 
					 | 
				
			||||||
    for (it = filesToWorkOn.cbegin(); it != filesToWorkOn.cend(); ++it) {
 | 
					 | 
				
			||||||
        m_worker->startProgressLoop();
 | 
					 | 
				
			||||||
        QString fToWorkOn = (*it).trimmed();
 | 
					 | 
				
			||||||
        fToWorkOn = QDir::cleanPath(m_customerRepository + QDir::separator() + fToWorkOn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static const QRegularExpression version("^.*dc2c[.][0-9][0-9][.][0-9][0-9][.]bin.*$");
 | 
					 | 
				
			||||||
        if (fToWorkOn.contains(version)) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            qInfo() << QString(80, '*');
 | 
					 | 
				
			||||||
            qInfo() << "DO-UPDATE FILE-TO-WORK-ON" << fToWorkOn;
 | 
					 | 
				
			||||||
            qInfo() << QString(80, '*');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i=0; i < 3; ++i) { // send explicit reuests to get
 | 
					    for (int i=0; i < 3; ++i) { // send explicit reuests to get
 | 
				
			||||||
                                // current SW/HW-versions
 | 
					                                // current SW/HW-versions
 | 
				
			||||||
@@ -560,36 +727,58 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
				
			|||||||
        QThread::sleep(1);
 | 
					        QThread::sleep(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            QString const hwVersion = m_hw->dc_getHWversion().toLower();
 | 
					    QString const &hwVersion = m_hw->dc_getHWversion().toLower().trimmed();
 | 
				
			||||||
            QString const fwVersion = m_hw->dc_getSWversion().toLower();
 | 
					    QString const &swVersion = m_hw->dc_getSWversion().toLower().trimmed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            qInfo() << "current dc-hardware-version" << hwVersion;
 | 
					    m_hw->dc_autoRequest(false);
 | 
				
			||||||
            qInfo() << "current dc-firmware-version" << fwVersion;
 | 
					    QThread::sleep(1); // make sure the timer-slots are inactive
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!hwVersion.isEmpty() && !swVersion.isEmpty()) {
 | 
				
			||||||
 | 
					        return QStringList() << hwVersion << swVersion;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return QStringList() << "DC HW-version not available"
 | 
				
			||||||
 | 
					                         << "DC SW-version not available";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
				
			||||||
 | 
					    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) {
 | 
				
			||||||
 | 
					        m_worker->startProgressLoop();
 | 
				
			||||||
 | 
					        QString const &fToWorkOn = QDir::cleanPath(m_customerRepository + QDir::separator() + it->trimmed());
 | 
				
			||||||
 | 
					#if UPDATE_DC == 1
 | 
				
			||||||
 | 
					        static const QRegularExpression version("^.*dc2c[.][0-9]{1,2}[.][0-9]{1,2}[.]bin.*$");
 | 
				
			||||||
 | 
					        if (fToWorkOn.contains(version)) {
 | 
				
			||||||
 | 
					            Utils::printInfoMsg("DO-UPDATE FILE-TO-WORK-ON " + fToWorkOn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            QFile fn(fToWorkOn);
 | 
					            QFile fn(fToWorkOn);
 | 
				
			||||||
            QFileInfo finfo(fn);
 | 
					            QFileInfo finfo(fn);
 | 
				
			||||||
            if (!fn.exists()) { // check for broken link
 | 
					            if (!fn.exists()) { // check for broken link
 | 
				
			||||||
                qCritical() << QString(80, '*');
 | 
					                Utils::printCriticalErrorMsg("DO-UPDATE FILE-TO-WORK-ON "
 | 
				
			||||||
                qCritical() << "FILE-TO-WORK-ON" << fn << "DOES NOT EXIST";
 | 
					                    + fToWorkOn + " DOES NOT EXIST");
 | 
				
			||||||
                qCritical() << QString(80, '*');
 | 
					 | 
				
			||||||
                res = false;
 | 
					                res = false;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (false) {
 | 
					                bool updateBinaryRes = true;
 | 
				
			||||||
                //if (fwVersion.startsWith(linkTarget.completeBaseName())) {
 | 
					 | 
				
			||||||
                //    qCritical() << "current dc-firmware-version" << fwVersion
 | 
					 | 
				
			||||||
                //                << "already installed";
 | 
					 | 
				
			||||||
                //    res = false;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    res = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                qInfo() << "DOWNLOADING" << finfo.completeBaseName() << "TO DC";
 | 
					                qInfo() << "DOWNLOADING" << finfo.completeBaseName() << "TO DC";
 | 
				
			||||||
#if UPDATE_DC == 1
 | 
					 | 
				
			||||||
                m_hw->dc_autoRequest(false);// default: turn auto-request setting off
 | 
					                m_hw->dc_autoRequest(false);// default: turn auto-request setting off
 | 
				
			||||||
                QThread::sleep(1);          // wait to be sure that there are no more
 | 
					                QThread::sleep(1);          // wait to be sure that there are no more
 | 
				
			||||||
                                            // commands sent to dc-hardware
 | 
					                                            // commands sent to dc-hardware
 | 
				
			||||||
                qInfo() << "SET AUTO-REQUEST=FALSE";
 | 
					                qInfo() << "SET AUTO-REQUEST=FALSE";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
 | 
					                if ((updateBinaryRes = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
 | 
				
			||||||
                    qCritical() << "downloaded binary" << fToWorkOn;
 | 
					                    qCritical() << "downloaded binary" << fToWorkOn;
 | 
				
			||||||
                    ++displayIndex;
 | 
					                    ++displayIndex;
 | 
				
			||||||
                    emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
					                    emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
				
			||||||
@@ -599,19 +788,23 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                m_hw->dc_autoRequest(true); // turn auto-request setting on
 | 
					                m_hw->dc_autoRequest(true); // turn auto-request setting on
 | 
				
			||||||
                qInfo() << "SET AUTO-REQUEST=TRUE";
 | 
					                qInfo() << "SET AUTO-REQUEST=TRUE";
 | 
				
			||||||
                    qInfo() << "WAIT 10 SECS TO RECEIVE RESPONSES...";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    QThread::sleep(10); // wait to be sure that responses
 | 
					                QStringList const &versions = Update::getDcSoftAndHardWareVersion();
 | 
				
			||||||
                                        // have been received
 | 
					                if (versions.size() >= 2) {
 | 
				
			||||||
                    qInfo() << "updated dc-hardware-version" << m_hw->dc_getHWversion();
 | 
					                    if (updateBinaryRes == true) {
 | 
				
			||||||
                    qInfo() << "updated dc-firmware-version" << m_hw->dc_getSWversion();
 | 
					                        qInfo() << "dc-hardware-version (UPDATED)" << versions[0];
 | 
				
			||||||
 | 
					                        qInfo() << "dc-firmware-version (UPDATED)" << versions[1];
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        qInfo() << "dc-hardware-version (NOT UPDATED)" << versions[0];
 | 
				
			||||||
 | 
					                        qInfo() << "dc-firmware-version (NOT UPDATED)" << versions[1];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                res = updateBinaryRes;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                }
 | 
					        if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if (fToWorkOn.contains("DC2C_print", Qt::CaseInsensitive)
 | 
					 | 
				
			||||||
         && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
					         && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
				
			||||||
            res = true;
 | 
					            res = true;
 | 
				
			||||||
#if UPDATE_PRINTER_TEMPLATES == 1
 | 
					 | 
				
			||||||
            int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
 | 
					            int i = fToWorkOn.indexOf("DC2C_print", Qt::CaseInsensitive);
 | 
				
			||||||
            int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
 | 
					            int const templateIdx = fToWorkOn.mid(i).midRef(10, 2).toInt();
 | 
				
			||||||
            if ((templateIdx < 1) || (templateIdx > 32)) {
 | 
					            if ((templateIdx < 1) || (templateIdx > 32)) {
 | 
				
			||||||
@@ -619,56 +812,52 @@ bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
 | 
				
			|||||||
                res = false;
 | 
					                res = false;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
 | 
					                if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
 | 
				
			||||||
                    qInfo() << "downloaded printer template"<< fToWorkOn;
 | 
					                    Utils::printInfoMsg(
 | 
				
			||||||
 | 
					                        QString("DOWNLOADED PRINTER TEMPLATE %1 WITH INDEX=%2")
 | 
				
			||||||
 | 
					                            .arg(fToWorkOn)
 | 
				
			||||||
 | 
					                            .arg(templateIdx));
 | 
				
			||||||
                    ++displayIndex;
 | 
					                    ++displayIndex;
 | 
				
			||||||
                    emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
					                    emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
 | 
				
			||||||
                          + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
					                          + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
				
			||||||
                            Worker::UPDATE_STEP_DONE);
 | 
					                            Worker::UPDATE_STEP_DONE);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
 | 
					        } else if (fToWorkOn.contains("DC2C_cash", Qt::CaseInsensitive)
 | 
				
			||||||
                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
					                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
				
			||||||
            res = true;
 | 
					            res = true;
 | 
				
			||||||
#if UPDATE_CASH_TEMPLATE == 1
 | 
					 | 
				
			||||||
            if ((res = updateCashConf(fToWorkOn))) {
 | 
					            if ((res = updateCashConf(fToWorkOn))) {
 | 
				
			||||||
                qInfo() << "downloaded cash template"<< fToWorkOn;
 | 
					                Utils::printInfoMsg(QString("DOWNLOADED CASH TEMPLATE %1").arg(fToWorkOn));
 | 
				
			||||||
                ++displayIndex;
 | 
					                ++displayIndex;
 | 
				
			||||||
                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
					                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
 | 
				
			||||||
                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
					                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
				
			||||||
                        Worker::UPDATE_STEP_DONE);
 | 
					                        Worker::UPDATE_STEP_DONE);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
 | 
					        } else if (fToWorkOn.contains("DC2C_conf", Qt::CaseInsensitive)
 | 
				
			||||||
                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
					                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
				
			||||||
            res = true;
 | 
					            res = true;
 | 
				
			||||||
#if UPDATE_CONF_TEMPLATE == 1
 | 
					 | 
				
			||||||
            if ((res= updateConfig(fToWorkOn))) {
 | 
					            if ((res= updateConfig(fToWorkOn))) {
 | 
				
			||||||
                qInfo() << "downloaded config template"<< fToWorkOn;
 | 
					                Utils::printInfoMsg(QString("DOWNLOADED CONFIG TEMPLATE %1").arg(fToWorkOn));
 | 
				
			||||||
                ++displayIndex;
 | 
					                ++displayIndex;
 | 
				
			||||||
                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
					                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
 | 
				
			||||||
                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
					                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
				
			||||||
                        Worker::UPDATE_STEP_DONE);
 | 
					                        Worker::UPDATE_STEP_DONE);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
 | 
					        } else if (fToWorkOn.contains("DC2C_device", Qt::CaseInsensitive)
 | 
				
			||||||
                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
					                && fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
 | 
				
			||||||
            res = true;
 | 
					            res = true;
 | 
				
			||||||
#if UPDATE_DEVICE_TEMPLATE == 1
 | 
					 | 
				
			||||||
            if ((res = updateDeviceConf(fToWorkOn))) {
 | 
					            if ((res = updateDeviceConf(fToWorkOn))) {
 | 
				
			||||||
                qInfo() << "downloaded device template"<< fToWorkOn;
 | 
					                Utils::printInfoMsg(QString("DOWNLOADED DEVICE TEMPLATE %1").arg(fToWorkOn));
 | 
				
			||||||
                ++displayIndex;
 | 
					                ++displayIndex;
 | 
				
			||||||
                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
 | 
					                emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(3, ' ') + QString(")")
 | 
				
			||||||
                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
					                      + QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
 | 
				
			||||||
                        Worker::UPDATE_STEP_DONE);
 | 
					                        Worker::UPDATE_STEP_DONE);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
 | 
					            qCritical() << "UNKNOWN JSON FILE NAME" << fToWorkOn;
 | 
				
			||||||
            res = false;
 | 
					            res = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        m_worker->stopProgressLoop();
 | 
					        // m_worker->stopProgressLoop();
 | 
				
			||||||
        m_worker->setProgress(100);
 | 
					        // m_worker->setProgress(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (res == false) {
 | 
					        if (res == false) {
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								update.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								update.h
									
									
									
									
									
								
							@@ -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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,30 +21,35 @@ class Worker;
 | 
				
			|||||||
class Update : public QObject {
 | 
					class Update : public QObject {
 | 
				
			||||||
    Q_OBJECT
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    hwinf *m_hw;
 | 
					    hwinf *m_hw = nullptr;
 | 
				
			||||||
    Worker *m_worker;
 | 
					    Worker *m_worker = nullptr;
 | 
				
			||||||
    char const *m_serialInterface;
 | 
					    char const *m_serialInterface;
 | 
				
			||||||
    char const *m_baudrate;
 | 
					    char const *m_baudrate;
 | 
				
			||||||
    QString m_customerRepository;
 | 
					    QString m_customerRepository;
 | 
				
			||||||
    QString m_customerNrStr;
 | 
					    QString m_customerNrStr;
 | 
				
			||||||
    QString m_branchName;
 | 
					    QString m_branchName;
 | 
				
			||||||
 | 
					    QString m_pluginName;
 | 
				
			||||||
    QString m_workingDir;
 | 
					    QString m_workingDir;
 | 
				
			||||||
    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 = ',');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    explicit Update(hwinf *hw,
 | 
					    explicit Update(Worker *worker,
 | 
				
			||||||
                    Worker *worker,
 | 
					 | 
				
			||||||
                    QString customerRepository,
 | 
					                    QString customerRepository,
 | 
				
			||||||
                    QString customerNrStr,
 | 
					                    QString customerNrStr,
 | 
				
			||||||
                    QString branchName,
 | 
					                    QString branchName,
 | 
				
			||||||
 | 
					                    QString plugInDir,
 | 
				
			||||||
 | 
					                    QString pluginName,
 | 
				
			||||||
                    QString workingDir,
 | 
					                    QString workingDir,
 | 
				
			||||||
                    bool dryRun = false,
 | 
					                    bool dryRun = false,
 | 
				
			||||||
                    QObject *parent = nullptr,
 | 
					                    QObject *parent = nullptr,
 | 
				
			||||||
@@ -52,6 +58,9 @@ public:
 | 
				
			|||||||
    virtual ~Update() override;
 | 
					    virtual ~Update() override;
 | 
				
			||||||
    bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
 | 
					    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 customerId() { return m_customerId; }
 | 
				
			||||||
    //QString const customerId() const { return m_customerId; }
 | 
					    //QString const customerId() const { return m_customerId; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,6 +94,7 @@ private:
 | 
				
			|||||||
    bool updateDeviceConf(QString jsFileToSendToDC);
 | 
					    bool updateDeviceConf(QString jsFileToSendToDC);
 | 
				
			||||||
    bool downloadJson(enum FileTypeJson type, int templateIdx,
 | 
					    bool downloadJson(enum FileTypeJson type, int templateIdx,
 | 
				
			||||||
                      QString jsFileToSendToDC) const;
 | 
					                      QString jsFileToSendToDC) const;
 | 
				
			||||||
 | 
					    QStringList getDcSoftAndHardWareVersion();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
    void readyReadStandardOutput();
 | 
					    void readyReadStandardOutput();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								update_dc_event.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								update_dc_event.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					#include "update_dc_event.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QEvent::Type UpdateDcEvent::customEventType = QEvent::None;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UpdateDcEvent::UpdateDcEvent(QObject const *sender,
 | 
				
			||||||
 | 
					                             UpdateStep updateStep,
 | 
				
			||||||
 | 
					                             int count,
 | 
				
			||||||
 | 
					                             QDateTime const &sendDateTime)
 | 
				
			||||||
 | 
					    : QEvent(UpdateDcEvent::type())
 | 
				
			||||||
 | 
					    , m_sender(sender)
 | 
				
			||||||
 | 
					    , m_updateStep(updateStep)
 | 
				
			||||||
 | 
					    , m_count(count)
 | 
				
			||||||
 | 
					    , m_sendDateTime(sendDateTime) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UpdateDcEvent::~UpdateDcEvent() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QEvent::Type UpdateDcEvent::type() {
 | 
				
			||||||
 | 
					    if (customEventType == QEvent::None) {
 | 
				
			||||||
 | 
					        int generatedType = QEvent::registerEventType();
 | 
				
			||||||
 | 
					        customEventType = static_cast<QEvent::Type>(generatedType);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return customEventType;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										40
									
								
								update_dc_event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								update_dc_event.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					#ifndef UPDATE_DC_EVENT_H_INCLUDED
 | 
				
			||||||
 | 
					#define UPDATE_DC_EVENT_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QEvent>
 | 
				
			||||||
 | 
					#include <QDateTime>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UpdateDcEvent : public QEvent {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    enum UpdateStep { NONE, DC_REBOOT, BL_START, BL_CHECK, BL_CHECK_AFTER_STOP, BL_IS_UP, BL_IS_DOWN, BL_STOP};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    QObject const *m_sender;
 | 
				
			||||||
 | 
					    UpdateStep m_updateStep;
 | 
				
			||||||
 | 
					    int m_count;
 | 
				
			||||||
 | 
					    QDateTime m_sendDateTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    explicit UpdateDcEvent(QObject const *sender, UpdateStep updateStep,
 | 
				
			||||||
 | 
					                           int count,
 | 
				
			||||||
 | 
					                           QDateTime const &sendDateTime = QDateTime::currentDateTime());
 | 
				
			||||||
 | 
					    virtual ~UpdateDcEvent();
 | 
				
			||||||
 | 
					    static QEvent::Type type();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QObject const *sender() { return m_sender; }
 | 
				
			||||||
 | 
					    QObject const *sender() const { return m_sender; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setUpdateStep(UpdateStep updateStep) { m_updateStep = updateStep; }
 | 
				
			||||||
 | 
					    UpdateStep updateStep() { return m_updateStep; }
 | 
				
			||||||
 | 
					    UpdateStep updateStep() const { return m_updateStep; }
 | 
				
			||||||
 | 
					    int count() const { return m_count; }
 | 
				
			||||||
 | 
					    void setCount(int count) { m_count = count; }
 | 
				
			||||||
 | 
					    QDateTime &sendDateTime() { return m_sendDateTime; }
 | 
				
			||||||
 | 
					    QDateTime const &sendDateTime() const { return m_sendDateTime; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    static QEvent::Type customEventType;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // PROGRESS_EVENT_H_INCLUDED
 | 
				
			||||||
							
								
								
									
										239
									
								
								utils.cpp
									
									
									
									
									
								
							
							
						
						
									
										239
									
								
								utils.cpp
									
									
									
									
									
								
							@@ -1,9 +1,20 @@
 | 
				
			|||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
#include "message_handler.h"
 | 
					#include "message_handler.h"
 | 
				
			||||||
 | 
					#include "git/git_client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined (Q_OS_UNIX) || defined (Q_OS_LINUX)
 | 
				
			||||||
 | 
					#include "unistd.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QFile>
 | 
					#include <QFile>
 | 
				
			||||||
#include <QTextStream>
 | 
					#include <QTextStream>
 | 
				
			||||||
#include <QDebug>
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					#include <QDir>
 | 
				
			||||||
 | 
					#include <QDirIterator>
 | 
				
			||||||
 | 
					#include <QRegularExpression>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Utils::read1stLineOfFile(QString fileName) {
 | 
					int Utils::read1stLineOfFile(QString fileName) {
 | 
				
			||||||
    QFile f(fileName);
 | 
					    QFile f(fileName);
 | 
				
			||||||
@@ -35,17 +46,90 @@ QString Utils::zoneName(quint8 i) {
 | 
				
			|||||||
    return "N/A";
 | 
					    return "N/A";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Utils::printCriticalErrorMsg(QString const &errorMsg) {
 | 
					void Utils::printCriticalErrorMsg(QString const &errorMsg, bool upper, bool lower) {
 | 
				
			||||||
    qCritical() << QString(80, '!');
 | 
					    if (upper) qCritical() << QString(80, 'E');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qCritical() << errorMsg;
 | 
					    qCritical() << errorMsg;
 | 
				
			||||||
    qCritical() << QString(80, '!');
 | 
					
 | 
				
			||||||
 | 
					    if (lower) qCritical() << QString(80, 'E');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Utils::printInfoMsg(QString const &infoMsg) {
 | 
					void Utils::printCriticalErrorMsg(QStringList const &errorMsg) {
 | 
				
			||||||
    qCritical() << QString(80, '=');
 | 
					    qCritical() << QString(80, 'E');
 | 
				
			||||||
    qCritical() << infoMsg;
 | 
					    for (int i = 0; i < errorMsg.size(); ++i) {
 | 
				
			||||||
    qCritical() << QString(80, '=');
 | 
					        qCritical() << errorMsg.at(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    qCritical() << QString(80, 'E');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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::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) {
 | 
					void Utils::printLineEditInfo(QStringList const &lines) {
 | 
				
			||||||
@@ -77,3 +161,144 @@ QString Utils::getTariffLoadTime(QString fileName) {
 | 
				
			|||||||
    return "N/A";
 | 
					    return "N/A";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Utils::rstrip(QString const &str) {
 | 
				
			||||||
 | 
					    int n = str.size() - 1;
 | 
				
			||||||
 | 
					    for (; n >= 0; --n) {
 | 
				
			||||||
 | 
					        if (!str.at(n).isSpace()) {
 | 
				
			||||||
 | 
					            return str.left(n + 1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Utils::sameFilesInDirs(QDir const &dir1, QDir const &dir2,
 | 
				
			||||||
 | 
					                            QStringList const &nameFilters) {
 | 
				
			||||||
 | 
					    if (!dir1.exists()) {
 | 
				
			||||||
 | 
					        printCriticalErrorMsg(dir1.dirName() + " DOES NOT EXIST");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!dir2.exists()) {
 | 
				
			||||||
 | 
					        printCriticalErrorMsg(dir2.dirName() + " DOES NOT EXIST");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (dir1.absolutePath() == dir2.absolutePath()) {
 | 
				
			||||||
 | 
					        printCriticalErrorMsg(dir1.dirName() + " AND "+ dir2.dirName() + " HAVE SAME PATH");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // files, sorted by name
 | 
				
			||||||
 | 
					    QFileInfoList const &lst1 = dir1.entryInfoList(nameFilters, QDir::Files, QDir::Name);
 | 
				
			||||||
 | 
					    QFileInfoList const &lst2 = dir2.entryInfoList(nameFilters, QDir::Files, QDir::Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QStringList fileNameLst1{};
 | 
				
			||||||
 | 
					    QStringList fileNameLst2{};
 | 
				
			||||||
 | 
					    QListIterator<QFileInfo> i1(lst1);
 | 
				
			||||||
 | 
					    while (i1.hasNext()) {
 | 
				
			||||||
 | 
					        fileNameLst1 << i1.next().fileName();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    QListIterator<QFileInfo> i2(lst2);
 | 
				
			||||||
 | 
					    while (i2.hasNext()) {
 | 
				
			||||||
 | 
					        fileNameLst2 << i2.next().fileName();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (fileNameLst1.isEmpty()) {
 | 
				
			||||||
 | 
					        qCritical() << "DIR1" << dir1.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (fileNameLst2.isEmpty())  {
 | 
				
			||||||
 | 
					        qCritical() << "DIR1" << dir2.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (fileNameLst1 != fileNameLst2) {
 | 
				
			||||||
 | 
					        printCriticalErrorMsg(dir1.dirName() + " AND " + dir2.dirName()
 | 
				
			||||||
 | 
					                            + " DIFFER: [" + fileNameLst1.join(',') + "],["
 | 
				
			||||||
 | 
					                            + fileNameLst2.join(',') + "]");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        printInfoMsg(dir1.dirName() + " AND " + dir2.dirName()
 | 
				
			||||||
 | 
					                    + " ARE EQUAL: [" + fileNameLst1.join(',') + "]");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QStringList gitBlobLst1{};
 | 
				
			||||||
 | 
					    QStringList gitBlobLst2{};
 | 
				
			||||||
 | 
					    QListIterator<QFileInfo> i3(lst1);
 | 
				
			||||||
 | 
					    while (i3.hasNext()) {
 | 
				
			||||||
 | 
					        gitBlobLst1 << GitClient::gitBlob(i3.next().fileName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    QListIterator<QFileInfo> i4(lst2);
 | 
				
			||||||
 | 
					    while (i4.hasNext()) {
 | 
				
			||||||
 | 
					        gitBlobLst2 << GitClient::gitBlob(i4.next().fileName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (gitBlobLst1.isEmpty()) {
 | 
				
			||||||
 | 
					        qCritical() << "DIR1" << dir1.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (gitBlobLst2.isEmpty())  {
 | 
				
			||||||
 | 
					        qCritical() << "DIR1" << dir2.dirName() << " DOES NOT CONTAIN EXPECTED FILES";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (gitBlobLst1 != gitBlobLst2) {
 | 
				
			||||||
 | 
					        printCriticalErrorMsg(dir1.dirName() + " AND " + dir2.dirName()
 | 
				
			||||||
 | 
					                            + " DIFFER: [" + gitBlobLst1.join(',') + "],["
 | 
				
			||||||
 | 
					                            + gitBlobLst2.join(',') + "]");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        printInfoMsg(dir1.dirName() + " AND " + dir2.dirName()
 | 
				
			||||||
 | 
					                    + " CONTAIN SAME GIT-BLOBS FOR FILES: [" + fileNameLst1.join(',') + "]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Utils::getParentName() { // get name of parent process
 | 
				
			||||||
 | 
					    QString ppid = QString("/proc/%1/status").arg(getppid());
 | 
				
			||||||
 | 
					    std::ifstream f(ppid.toStdString().c_str());
 | 
				
			||||||
 | 
					    if (f.is_open()) {
 | 
				
			||||||
 | 
					        std::string next;
 | 
				
			||||||
 | 
					        while (std::getline(f, next)) {
 | 
				
			||||||
 | 
					            QString line = QString(next.c_str()).simplified();
 | 
				
			||||||
 | 
					            if (line.startsWith("Name")) {
 | 
				
			||||||
 | 
					                int const idx = line.indexOf(QChar(':'));
 | 
				
			||||||
 | 
					                if (idx != -1) {
 | 
				
			||||||
 | 
					                    return line.mid(idx+1).trimmed();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Utils::isATBQTRunning() {
 | 
				
			||||||
 | 
					    QDirIterator it("/proc",
 | 
				
			||||||
 | 
					                    QStringList() << "status",
 | 
				
			||||||
 | 
					                    QDir::Files,
 | 
				
			||||||
 | 
					                    QDirIterator::Subdirectories);
 | 
				
			||||||
 | 
					    while (it.hasNext()) {
 | 
				
			||||||
 | 
					        QString const &nextStatusFile = it.next();
 | 
				
			||||||
 | 
					        static const QRegularExpression re("^/proc/[0-9]{1,}/status");
 | 
				
			||||||
 | 
					        QRegularExpressionMatch match = re.match(nextStatusFile);
 | 
				
			||||||
 | 
					        if (match.hasMatch()) {
 | 
				
			||||||
 | 
					            std::ifstream f(nextStatusFile.toStdString().c_str());
 | 
				
			||||||
 | 
					            if (f.is_open()) {
 | 
				
			||||||
 | 
					                std::string next;
 | 
				
			||||||
 | 
					                while (std::getline(f, next)) {
 | 
				
			||||||
 | 
					                    QString line = QString(next.c_str()).simplified();
 | 
				
			||||||
 | 
					                    if (line.startsWith("Name")) {
 | 
				
			||||||
 | 
					                        int const idx = line.indexOf(QChar(':'));
 | 
				
			||||||
 | 
					                        if (idx != -1) {
 | 
				
			||||||
 | 
					                            QString const binary = line.mid(idx+1).trimmed();
 | 
				
			||||||
 | 
					                            if (binary == "ATBQT") {
 | 
				
			||||||
 | 
					                                return true;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								utils.h
									
									
									
									
									
								
							@@ -7,14 +7,29 @@
 | 
				
			|||||||
#include <QFile>
 | 
					#include <QFile>
 | 
				
			||||||
#include <QFileInfo>
 | 
					#include <QFileInfo>
 | 
				
			||||||
#include <QDateTime>
 | 
					#include <QDateTime>
 | 
				
			||||||
 | 
					#include <QDir>
 | 
				
			||||||
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Utils {
 | 
					namespace Utils {
 | 
				
			||||||
    int read1stLineOfFile(QString fileName);
 | 
					    int read1stLineOfFile(QString fileName);
 | 
				
			||||||
    QString zoneName(quint8 i);
 | 
					    QString zoneName(quint8 i);
 | 
				
			||||||
    void printCriticalErrorMsg(QString const &errorMsg);
 | 
					    void printCriticalErrorMsg(QString const &errorMsg, bool upper=false, bool lower=false);
 | 
				
			||||||
    void printInfoMsg(QString const &infoMsg);
 | 
					    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);
 | 
					    void printLineEditInfo(QStringList const &lines);
 | 
				
			||||||
    QString getTariffLoadTime(QString fileName);
 | 
					    QString getTariffLoadTime(QString fileName);
 | 
				
			||||||
 | 
					    QString rstrip(QString const &str);
 | 
				
			||||||
 | 
					    bool sameFilesInDirs(QDir const &dir1, QDir const &dir2,
 | 
				
			||||||
 | 
					                         QStringList const &nameFilters = {"*.json"});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString getParentName();
 | 
				
			||||||
 | 
					    bool isATBQTRunning();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // UTILS_H_INCLUDED
 | 
					#endif // UTILS_H_INCLUDED
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1611
									
								
								worker.cpp
									
									
									
									
									
								
							
							
						
						
									
										1611
									
								
								worker.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user