Compare commits
16 Commits
1ddd0074b3
...
6a4a852fd6
Author | SHA1 | Date | |
---|---|---|---|
6a4a852fd6 | |||
81a9304438 | |||
332d689b8c | |||
b508c0517d | |||
d2c0fdf820 | |||
7293afd203 | |||
2fd1053bf9 | |||
e0a68a35f4 | |||
4e277b4ca6 | |||
b3f4a4086b | |||
eb7d77692b | |||
ce1b1859df | |||
371cc1a187 | |||
a94606ca89 | |||
5c9c9dc917 | |||
ab8acfc7d1 |
@ -1,10 +1,20 @@
|
|||||||
# QT -= gui
|
QT += core gui
|
||||||
QT += core
|
|
||||||
QT += widgets serialport network
|
QT += widgets serialport network
|
||||||
# QT += network
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
TARGET = ATBUpdateTool
|
TARGET = ATBUpdateTool
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any Qt feature that has been marked deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
VERSION=1.0.0
|
VERSION=1.0.0
|
||||||
|
|
||||||
INCLUDEPATH += plugins
|
INCLUDEPATH += plugins
|
||||||
@ -67,10 +77,10 @@ contains( CONFIG, DesktopLinux ) {
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
mainwindow.cpp \
|
||||||
|
utils.cpp \
|
||||||
update.cpp \
|
update.cpp \
|
||||||
git/git_client.cpp \
|
git/git_client.cpp \
|
||||||
apism/apism_client.cpp \
|
|
||||||
apism/apism_tcp_client.cpp \
|
|
||||||
ismas/ismas_client.cpp \
|
ismas/ismas_client.cpp \
|
||||||
process/command.cpp \
|
process/command.cpp \
|
||||||
message_handler.cpp \
|
message_handler.cpp \
|
||||||
@ -79,9 +89,9 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
update.h \
|
update.h \
|
||||||
|
utils.h \
|
||||||
|
mainwindow.h \
|
||||||
git/git_client.h \
|
git/git_client.h \
|
||||||
apism/apism_client.h \
|
|
||||||
apism/apism_tcp_client.h \
|
|
||||||
apism/ismas_data.h \
|
apism/ismas_data.h \
|
||||||
ismas/ismas_client.h \
|
ismas/ismas_client.h \
|
||||||
process/command.h \
|
process/command.h \
|
||||||
@ -90,6 +100,9 @@ HEADERS += \
|
|||||||
worker_thread.h \
|
worker_thread.h \
|
||||||
plugins/interfaces.h
|
plugins/interfaces.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwindow.ui
|
||||||
|
|
||||||
OTHER_FILES += \
|
OTHER_FILES += \
|
||||||
/opt/app/tools/atbupdate/update_log.csv \
|
/opt/app/tools/atbupdate/update_log.csv \
|
||||||
main.cpp.bck \
|
main.cpp.bck \
|
||||||
@ -100,3 +113,8 @@ OTHER_FILES += \
|
|||||||
# git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
|
# 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
|
# git subtree pull --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
|
||||||
# include(./DCPlugin/DCPlugin.pri)
|
# include(./DCPlugin/DCPlugin.pri)
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
@ -1,816 +0,0 @@
|
|||||||
#include "apism_client.h"
|
|
||||||
//#include "support/VendingData.h"
|
|
||||||
//#include "support/PersistentData.h"
|
|
||||||
//#include "support/utils.h"
|
|
||||||
//#include "ATBHMIconfig.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QHostAddress>
|
|
||||||
#include <QString>
|
|
||||||
#include <QList>
|
|
||||||
#include <QListIterator>
|
|
||||||
#include <QScopedPointer>
|
|
||||||
#include <QUuid>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
// Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
|
|
||||||
|
|
||||||
ApismClient::ApismClient(QObject *eventReceiver, ATBHMIconfig *config, PersistentData *persistentData, QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, healthEventReceiver(eventReceiver)
|
|
||||||
, m_config(config)
|
|
||||||
, persistentData(persistentData)
|
|
||||||
, lastError(0)
|
|
||||||
, lastErrorDescription("")
|
|
||||||
, currentRequestUid("")
|
|
||||||
, currentRequest(ISMAS::REQUEST::NO_REQUEST)
|
|
||||||
{
|
|
||||||
this->apismTcpSendClient = new ApismTcpClient("127.0.0.1", "7777", this);
|
|
||||||
this->apismTcpRequestResponseClient = new ApismTcpClient("127.0.0.1", "7778", this);
|
|
||||||
|
|
||||||
connect(apismTcpRequestResponseClient, &ApismTcpClient::receivedData,
|
|
||||||
this, &ApismClient::onReceivedResponse);
|
|
||||||
connect(apismTcpRequestResponseClient, &ApismTcpClient::responseTimeout,
|
|
||||||
this, &ApismClient::onRequestResponseClientResponseTimeout);
|
|
||||||
connect(apismTcpSendClient, &ApismTcpClient::responseTimeout,
|
|
||||||
this, &ApismClient::onSendClientResponseTimeout);
|
|
||||||
connect(this, SIGNAL(sendCmdSendVersionToIsmas(QString)),
|
|
||||||
this, SLOT(onSendCmdSendVersionToIsmas(QString)));
|
|
||||||
|
|
||||||
// not needed as APISM closes the socket after we send data, so readyRead()
|
|
||||||
// might not even fire
|
|
||||||
// connect(&m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
|
||||||
|
|
||||||
// defined for Qt >= 5.15, we have 5.12
|
|
||||||
// qRegisterMetaType<QAbstractSocket::SocketError>();
|
|
||||||
// connect(&m_socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
|
|
||||||
// this, SLOT(onSocketError(&QAbstractSocket::SocketError)));
|
|
||||||
}
|
|
||||||
|
|
||||||
ApismClient::~ApismClient() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::restartApism() {
|
|
||||||
QProcess::startDetached("/bin/systemctl", {"restart", "apism"});
|
|
||||||
}
|
|
||||||
|
|
||||||
//void ApismClient::onReadyRead() { // parse APISM response
|
|
||||||
// QByteArray data = m_socket.readAll();
|
|
||||||
// qCritical() << "APISM-RESPONSE = (" << endl << data << endl << ")";
|
|
||||||
//}
|
|
||||||
|
|
||||||
void ApismClient::sendTransaction(const VendingData *vendingData) {
|
|
||||||
|
|
||||||
Q_UNUSED(vendingData);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
QScopedPointer<ISMAS::TransferData> transferData(new ISMAS::TransferData());
|
|
||||||
|
|
||||||
PAYMENT_VARIANTS::TYPE paymentType = vendingData->getParameter("PaymentType").value<PAYMENT_VARIANTS::TYPE>();
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////// DEVICE //////////////////////////////////
|
|
||||||
bool deviceSet = false;
|
|
||||||
//QJsonValue tariffId("TariffInfo");
|
|
||||||
//transferData->device.insert("TARIFID", tariffId);
|
|
||||||
//QJsonValue group("group");
|
|
||||||
//transferData->device.insert("GROUP", group);
|
|
||||||
//QJsonValue zone("zone");
|
|
||||||
//transferData->device.insert("ZONE", zone);
|
|
||||||
if (deviceSet) {
|
|
||||||
transferData->insert("DEVICE", transferData->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////// TRANSACTION /////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
bool transactionSet = false;
|
|
||||||
|
|
||||||
if (vendingData->hasParameter("TRANSACTION_STATE")) {
|
|
||||||
QVariant tstate = vendingData->getParameter("TRANSACTION_STATE");
|
|
||||||
if (tstate.isValid() && tstate.type() == QVariant::Int) {
|
|
||||||
transferData->transaction.state = tstate.toInt();
|
|
||||||
transferData->transaction.insert("STATE", transferData->transaction.state);
|
|
||||||
transactionSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("TRANSACTION_UID")) {
|
|
||||||
QVariant tuid = vendingData->getParameter("TRANSACTION_UID");
|
|
||||||
if (tuid.isValid() && tuid.type() == QVariant::String) {
|
|
||||||
transferData->transaction.uid = tuid.toString();
|
|
||||||
transferData->transaction.insert("UID", transferData->transaction.uid);
|
|
||||||
this->persistentData->setLastTransactionUID(tuid.toString());
|
|
||||||
transactionSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("TRANSACTION_TIMESTAMP")) {
|
|
||||||
QVariant tstamp = vendingData->getParameter("TRANSACTION_TIMESTAMP");
|
|
||||||
if (tstamp.isValid() && tstamp.type() == QVariant::String) {
|
|
||||||
transferData->transaction.timestamp = tstamp.toString();
|
|
||||||
transferData->transaction.insert("TIMESTAMP", transferData->transaction.timestamp);
|
|
||||||
transactionSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("TRANSACTION_TICKET_SEQUENCE_NUMBER")) {
|
|
||||||
QVariant tsn = vendingData->getParameter("TRANSACTION_TICKET_SEQUENCE_NUMBER");
|
|
||||||
if (tsn.isValid() && tsn.type() == QVariant::Int) {
|
|
||||||
transferData->transaction.seq_tick_number = tsn.toInt();
|
|
||||||
transferData->transaction.insert("TICKETNU", transferData->transaction.seq_tick_number);
|
|
||||||
transactionSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("LICENSEPLATE")) {
|
|
||||||
QVariant lp = vendingData->getParameter("LICENSEPLATE");
|
|
||||||
transferData->transaction.userText = QJsonValue::fromVariant(lp);
|
|
||||||
transferData->transaction.insert("USERTEXT", transferData->transaction.userText);
|
|
||||||
transferData->transaction.userTextType = "license plate";
|
|
||||||
transferData->transaction.insert("USERTEXTTYPE", transferData->transaction.userTextType);
|
|
||||||
transactionSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transactionSet) {
|
|
||||||
transferData->insert("TRANSACTION", transferData->transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////// ITEM //////////////////////////////////
|
|
||||||
bool itemSet = false;
|
|
||||||
|
|
||||||
if (vendingData->hasParameter("PermitType")) {
|
|
||||||
QVariant idVariant = vendingData->getParameter("PermitType");
|
|
||||||
transferData->item.id = idVariant.toString();
|
|
||||||
transferData->item.insert("ID", transferData->item.id);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("Product")) {
|
|
||||||
QVariant nameVariant = vendingData->getParameter("Product");
|
|
||||||
transferData->item.name = nameVariant.toString();
|
|
||||||
transferData->item.insert("NAME", transferData->item.name);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("PRICE_INFO_GROSS")) {
|
|
||||||
int priceUint = vendingData->getUintParameter("PRICE_INFO_GROSS");
|
|
||||||
transferData->item.price = priceUint;
|
|
||||||
transferData->item.insert("PRICE", transferData->item.price);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("PERIOD_START")) {
|
|
||||||
QVariant startTimeVariant = vendingData->getParameter("PERIOD_START");
|
|
||||||
transferData->item.startTime = utils::getISODateTimeWithMsAndOffset(startTimeVariant);
|
|
||||||
transferData->item.insert("STARTTIME", transferData->item.startTime);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("PERIOD_END")) {
|
|
||||||
QVariant endTimeVariant = vendingData->getParameter("PERIOD_END");
|
|
||||||
transferData->item.endTime = utils::getISODateTimeWithMsAndOffset(endTimeVariant);
|
|
||||||
transferData->item.insert("ENDTIME", transferData->item.endTime);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("ITEM_PRINT_TEXT")) {
|
|
||||||
QVariant textVariant = vendingData->getParameter("ITEM_PRINT_TEXT");
|
|
||||||
transferData->item.printText = textVariant.toString();
|
|
||||||
transferData->item.insert("PRINTTEXT", transferData->item.printText);
|
|
||||||
itemSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set static data:
|
|
||||||
|
|
||||||
// currency
|
|
||||||
if (itemSet) {
|
|
||||||
transferData->item.currency = this->m_config->getPaymentCurrencyISOCode();
|
|
||||||
transferData->item.insert("CURRENCY", transferData->item.currency);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemSet) {
|
|
||||||
transferData->insert("ITEM", transferData->item);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////// PAYMENT //////////////////////////////
|
|
||||||
bool paymentSet = false;
|
|
||||||
|
|
||||||
/////////////////////////// PAYMENT.CASH /////////////////////////////
|
|
||||||
if (paymentType == PAYMENT_VARIANTS::TYPE::CASH) {
|
|
||||||
bool cashSet = false;
|
|
||||||
|
|
||||||
if (vendingData->hasParameter("PaymentCashCoins")) {
|
|
||||||
QVariant coins = vendingData->getParameter("PaymentCashCoins");
|
|
||||||
transferData->payment.cash.coins = coins.toInt();
|
|
||||||
transferData->payment.cash.insert("COINS", transferData->payment.cash.coins);
|
|
||||||
cashSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("PaymentCashChange")) {
|
|
||||||
QVariant change = vendingData->getParameter("PaymentCashChange");
|
|
||||||
transferData->payment.cash.change = change.toInt();
|
|
||||||
transferData->payment.cash.insert("CHANGE", transferData->payment.cash.change);
|
|
||||||
cashSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("PaymentCashOverpaid")) {
|
|
||||||
QVariant overpaid = vendingData->getParameter("PaymentCashOverpaid");
|
|
||||||
transferData->payment.cash.overpaid = overpaid.toInt();
|
|
||||||
transferData->payment.cash.insert("OVERPAID", transferData->payment.cash.overpaid);
|
|
||||||
cashSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// currency
|
|
||||||
if (cashSet) {
|
|
||||||
transferData->payment.cash.currency = this->m_config->getPaymentCurrencyISOCode();
|
|
||||||
transferData->payment.cash.insert("CURRENCY", transferData->payment.cash.currency);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cashSet) {
|
|
||||||
transferData->payment.insert("CASH", transferData->payment.cash);
|
|
||||||
paymentSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////// PAYMENT.CARD /////////////////////////////
|
|
||||||
if (paymentType == PAYMENT_VARIANTS::TYPE::CARD) {
|
|
||||||
paymentSet = true;
|
|
||||||
bool cardSet = true;
|
|
||||||
|
|
||||||
|
|
||||||
transferData->payment.card.insert("CARDNU", "unknown");
|
|
||||||
|
|
||||||
transferData->payment.card.insert("VALUE", transferData->item.price);
|
|
||||||
|
|
||||||
transferData->payment.card.insert("CARDTYPE", "unknown");
|
|
||||||
|
|
||||||
|
|
||||||
transferData->payment.card.currency = this->m_config->getPaymentCurrencyISOCode();
|
|
||||||
transferData->payment.card.insert("CURRENCY", transferData->payment.card.currency);
|
|
||||||
|
|
||||||
// transferData->payment.card.insert("TERMINALID", tid);
|
|
||||||
//transferData->payment.card.insert("TERMINALRESULT", tresult);
|
|
||||||
|
|
||||||
if (cardSet) {
|
|
||||||
transferData->payment.insert("CARD", transferData->payment.card);
|
|
||||||
paymentSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paymentSet) {
|
|
||||||
transferData->insert("PAYMENT", transferData->payment);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////// RESULT /////////////////////////////////
|
|
||||||
bool resultSet = false;
|
|
||||||
|
|
||||||
|
|
||||||
if (vendingData->hasParameter("RESULT_DELIVERY")) {
|
|
||||||
QVariant delVariant = vendingData->getParameter("RESULT_DELIVERY");
|
|
||||||
transferData->result.delivery = delVariant.toJsonValue();
|
|
||||||
transferData->result.insert("DELIVERY", transferData->result.delivery);
|
|
||||||
resultSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("RESULT_RESULT")) {
|
|
||||||
QVariant resVariant = vendingData->getParameter("RESULT_RESULT");
|
|
||||||
transferData->result.result = resVariant.toJsonValue();
|
|
||||||
transferData->result.insert("RESULT", transferData->result.result);
|
|
||||||
resultSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("RESULT_ERROR_CODE")) {
|
|
||||||
QVariant ecVariant = vendingData->getParameter("RESULT_ERROR_CODE");
|
|
||||||
transferData->result.errorCode = ecVariant.toJsonValue();
|
|
||||||
transferData->result.insert("ERRORCODE", transferData->result.errorCode);
|
|
||||||
resultSet = true;
|
|
||||||
}
|
|
||||||
if (vendingData->hasParameter("RESULT_ERROR_MESSAGE")) {
|
|
||||||
QVariant emsgVariant = vendingData->getParameter("RESULT_ERROR_MESSAGE");
|
|
||||||
transferData->result.errorMsg = emsgVariant.toJsonValue();
|
|
||||||
transferData->result.insert("ERRORMSG", transferData->result.errorMsg);
|
|
||||||
resultSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultSet) {
|
|
||||||
transferData->insert("RESULT", transferData->result);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*transferData);
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_TRANSACTION#J=";
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApismClient::sendAccount(const QHash<QString, QVariant> & accountDataHash)
|
|
||||||
{
|
|
||||||
QScopedPointer<ISMAS::AccountData> accountData(new ISMAS::AccountData());
|
|
||||||
|
|
||||||
accountData->coinBox.UID = QUuid::createUuid().toString(QUuid::WithoutBraces); // .mid(0, 8)
|
|
||||||
accountData->insert("UID", accountData->coinBox.UID);
|
|
||||||
|
|
||||||
accountData->coinBox.ChangeNumber = QJsonValue(static_cast<qint32>(this->persistentData->getNewCoinboxChangeNumber()));
|
|
||||||
accountData->insert("COINBOX_CHANGE_NUMBER", accountData->coinBox.ChangeNumber);
|
|
||||||
|
|
||||||
accountData->coinBox.Process = "COINBOX_CHANGE";
|
|
||||||
accountData->insert("PROCESS", accountData->coinBox.Process);
|
|
||||||
|
|
||||||
accountData->insert("StartTime", utils::getISODateTimeWithMsAndOffset(persistentData->getAccountStartTime()));
|
|
||||||
accountData->insert("EndTime", utils::getCurrentISODateTimeWithMsAndOffset());
|
|
||||||
accountData->insert("StartHash", persistentData->getFirstTransactionUID());
|
|
||||||
accountData->insert("EndHash", persistentData->getLastTransactionUID());
|
|
||||||
|
|
||||||
// coins
|
|
||||||
int numberOfCoinVariants = accountDataHash["NumberOfCoinVariants"].toInt();
|
|
||||||
for (int i=0; i < numberOfCoinVariants;++i) {
|
|
||||||
accountData->coinBox.coin.value = accountDataHash["COIN_" + QString::number(i) + "_Value"].toInt();
|
|
||||||
accountData->coinBox.coin.numberOfCoins = accountDataHash["COIN_" + QString::number(i) + "_Quantity"].toInt();
|
|
||||||
accountData->coinBox.coin.insert("VALUE", accountData->coinBox.coin.value);
|
|
||||||
accountData->coinBox.coin.insert("QUANTITY", accountData->coinBox.coin.numberOfCoins);
|
|
||||||
|
|
||||||
if (accountDataHash.contains("COIN_" + QString::number(i) + "_Currency")) {
|
|
||||||
accountData->coinBox.coin.currency = accountDataHash["COIN_" + QString::number(i) + "_Currency"].toString();
|
|
||||||
accountData->coinBox.coin.insert("CURRENCY", accountData->coinBox.coin.numberOfCoins);
|
|
||||||
}
|
|
||||||
|
|
||||||
accountData->insert("COIN_" + QString::number(i), accountData->coinBox.coin);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*accountData);
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_CashboxChange#J=";
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
|
|
||||||
this->persistentData->clearForNewAccount();
|
|
||||||
|
|
||||||
persistentData->serializeToFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ApismClient::sendEvent(const ATBMachineEvent* machineEvent)
|
|
||||||
{
|
|
||||||
QScopedPointer<ISMAS::EventData> eventData(new ISMAS::EventData());
|
|
||||||
|
|
||||||
eventData->machineEvent.eventID = machineEvent->eventId;
|
|
||||||
eventData->insert("EVENT_ID", eventData->machineEvent.eventID);
|
|
||||||
|
|
||||||
eventData->machineEvent.deviceName = machineEvent->deviceName;
|
|
||||||
eventData->insert("DeviceName", eventData->machineEvent.deviceName);
|
|
||||||
|
|
||||||
eventData->machineEvent.reason = ATBMachineEvent::getEventClassString(machineEvent->machineEventClass);
|
|
||||||
eventData->insert("Reason", eventData->machineEvent.reason);
|
|
||||||
|
|
||||||
eventData->machineEvent.event = machineEvent->eventName;
|
|
||||||
eventData->insert("Event", eventData->machineEvent.event);
|
|
||||||
|
|
||||||
eventData->machineEvent.eventState = machineEvent->eventState;
|
|
||||||
eventData->insert("EventState", eventData->machineEvent.eventState);
|
|
||||||
|
|
||||||
eventData->machineEvent.timeStamp = machineEvent->timestamString;
|
|
||||||
eventData->insert("Timestamp", eventData->machineEvent.timeStamp);
|
|
||||||
|
|
||||||
eventData->machineEvent.parameter = machineEvent->parameterString;
|
|
||||||
eventData->insert("Parameter", eventData->machineEvent.parameter);
|
|
||||||
|
|
||||||
eventData->machineEvent.secondLevelInfo = machineEvent->secondLevelInfoString;
|
|
||||||
eventData->insert("SecondLevelInfo", eventData->machineEvent.secondLevelInfo);
|
|
||||||
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*eventData);
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_EVENT#J=";
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::requestAvailableIsmasUpdates() {
|
|
||||||
QByteArray data = "#M=APISM #C=REQ_ISMASParameter #J={}";
|
|
||||||
this->currentRequest = ISMAS::REQUEST::ISMAS_PARAMETER;
|
|
||||||
this->apismTcpRequestResponseClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::onSendCmdEventToIsmas(QString msg) {
|
|
||||||
QJsonParseError parseError;
|
|
||||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
|
||||||
qCritical() << "INVALID JSON MSG: PARSING FAILED:"
|
|
||||||
<< parseError.error << parseError.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!document.isObject()) {
|
|
||||||
qCritical() << "FILE IS NOT A JSON OBJECT!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_EVENT#J=";
|
|
||||||
data += document.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::onSendCmdSendVersionToIsmas(QString msg) {
|
|
||||||
QJsonParseError parseError;
|
|
||||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
|
||||||
qCritical() << "INVALID JSON MSG: PARSING FAILED:"
|
|
||||||
<< parseError.error << parseError.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!document.isObject()) {
|
|
||||||
qCritical() << "FILE IS NOT A JSON OBJECT!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_SENDVERSION#J=";
|
|
||||||
data += document.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::emulateUpdatesAvailable(QString const &msg) {
|
|
||||||
qDebug() << "EMULATE UPDATES AVAILABLE. MSG=" << msg;
|
|
||||||
onSendCmdEventToIsmas(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::sendState(const QString & state, const QString & msg)
|
|
||||||
{
|
|
||||||
qCritical() << "ApismClient::sendState(): ";
|
|
||||||
qCritical() << " state: " << state;
|
|
||||||
qCritical() << " msg: " << msg;
|
|
||||||
|
|
||||||
QJsonParseError parseError;
|
|
||||||
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
|
||||||
qCritical() << "ApismClient::sendState() invalid json msg: Parsing failed:" << parseError.error << parseError.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!document.isObject()) {
|
|
||||||
qCritical() << "File is not JSON object!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QScopedPointer<ISMAS::StateData> stateData(new ISMAS::StateData());
|
|
||||||
|
|
||||||
QJsonObject stateObject = document.object();
|
|
||||||
|
|
||||||
QJsonArray statesArray;
|
|
||||||
statesArray.append(stateObject);
|
|
||||||
|
|
||||||
// stateData->insert("TIMESTAMP", utils::getCurrentISODateTimeWithMsAndOffset());
|
|
||||||
// stateData->insert("HW_States", statesArray);
|
|
||||||
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*stateData);
|
|
||||||
QByteArray data = "#M=APISM#C=CMD_HW_STATUS#J=";
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpSendClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void ApismClient::sendMininformStartRequest(const VendingData* vendingData)
|
|
||||||
{
|
|
||||||
this->currentRequest = ISMAS::REQUEST::START;
|
|
||||||
|
|
||||||
struct MininFormTransferData : public QJsonObject {
|
|
||||||
struct : public QJsonObject {
|
|
||||||
QJsonValue uid; // MUST: uuid -> vendorId
|
|
||||||
QJsonValue posid; // terminal-id
|
|
||||||
QJsonValue authCode; // approval-code
|
|
||||||
QJsonValue stan; // MUST
|
|
||||||
QJsonValue lpn;
|
|
||||||
QJsonValue transactionTime; // MUST: Zeitstempel Verkauf
|
|
||||||
QJsonValue parkingStartTime; // MUST: Startzeit
|
|
||||||
QJsonValue preAuthAmount;
|
|
||||||
QJsonValue hourlyRate;
|
|
||||||
QJsonValue vehicleCategory;
|
|
||||||
QJsonValue langCode;
|
|
||||||
QJsonValue zoneCode;
|
|
||||||
} startAction;
|
|
||||||
};
|
|
||||||
|
|
||||||
QScopedPointer<MininFormTransferData> transferData(new MininFormTransferData());
|
|
||||||
|
|
||||||
transferData->startAction.uid = vendingData->getParameter("START_UID").toJsonValue();
|
|
||||||
this->currentRequestUid = vendingData->getParameter("START_UID").toString();
|
|
||||||
transferData->startAction.insert("UID", transferData->startAction.uid);
|
|
||||||
|
|
||||||
transferData->startAction.insert("POSID", vendingData->getParameter("START_POSID").toString());
|
|
||||||
|
|
||||||
transferData->startAction.insert("AUTHCODE", vendingData->getParameter("START_AuthCode").toString());
|
|
||||||
|
|
||||||
transferData->startAction.insert("STAN", vendingData->getParameter("START_STAN").toString());
|
|
||||||
|
|
||||||
transferData->startAction.insert("LPN", vendingData->getParameter("LICENSEPLATE").toString());
|
|
||||||
|
|
||||||
transferData->startAction.insert("TRANSACTIONTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("START_TRANSACTIONTIME").toString()));
|
|
||||||
|
|
||||||
transferData->startAction.insert("STARTTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("START_STARTTIME").toString()));
|
|
||||||
|
|
||||||
transferData->startAction.insert("AMOUNT", static_cast<int>(vendingData->getUintParameter("PRICE_INFO_GROSS")));
|
|
||||||
|
|
||||||
transferData->startAction.insert("RATE_H", static_cast<int>(vendingData->getUintParameter("PRICE_INFO_RATE_H")));
|
|
||||||
|
|
||||||
transferData->startAction.insert("VEHICLETYPE", "01"); // Fixed value
|
|
||||||
|
|
||||||
transferData->startAction.insert("LANGUAGE", "HUN"); // Fixed value
|
|
||||||
|
|
||||||
transferData->startAction.insert("ZONE", vendingData->getParameter("MININFORM_ZONE").toString());
|
|
||||||
|
|
||||||
transferData->insert("STARTACTION", transferData->startAction);
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*transferData);
|
|
||||||
QByteArray data = "#M=APISM#C=REQ_START#J="; // REQ_... -> use port 7778
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpRequestResponseClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::sendMininformStopRequest(const VendingData* vendingData)
|
|
||||||
{
|
|
||||||
this->currentRequest = ISMAS::REQUEST::STOP;
|
|
||||||
|
|
||||||
struct MininFormTransferData : public QJsonObject {
|
|
||||||
struct : public QJsonObject {
|
|
||||||
QJsonObject uid; // MUST: uuid
|
|
||||||
QJsonObject posid; // terminal-id
|
|
||||||
QJsonObject stan; // MUST
|
|
||||||
QJsonObject lpn; // MUST
|
|
||||||
QJsonObject stopTime; // MUST: Stop-Zeit
|
|
||||||
QJsonObject langCode;
|
|
||||||
QJsonObject deviceId;
|
|
||||||
} stopAction;
|
|
||||||
};
|
|
||||||
|
|
||||||
QScopedPointer<MininFormTransferData> transferData(new MininFormTransferData());
|
|
||||||
|
|
||||||
this->currentRequestUid = QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 8);
|
|
||||||
transferData->stopAction.insert("UID", this->currentRequestUid);
|
|
||||||
|
|
||||||
transferData->stopAction.insert("POSID", vendingData->getParameter("STOP_POSID").toString());
|
|
||||||
|
|
||||||
transferData->stopAction.insert("STAN", vendingData->getParameter("STOP_STAN").toString());
|
|
||||||
|
|
||||||
transferData->stopAction.insert("LPN", vendingData->getParameter("LICENSEPLATE").toString());
|
|
||||||
|
|
||||||
transferData->stopAction.insert("STOPTIME", utils::getISODateTimeWithMsAndOffset(vendingData->getParameter("STOP_STOPTIME")));
|
|
||||||
|
|
||||||
transferData->stopAction.insert("LANGUAGE", "HUN"); // Fixed value
|
|
||||||
|
|
||||||
transferData->stopAction.insert("DEVICE_ID", this->m_config->getMachineNr());
|
|
||||||
|
|
||||||
transferData->insert("STOPACTION", transferData->stopAction);
|
|
||||||
|
|
||||||
QJsonDocument jsonDoc(*transferData);
|
|
||||||
QByteArray data = "#M=APISM#C=REQ_STOP#J="; // REQ_ -> use port 7778
|
|
||||||
data += jsonDoc.toJson(QJsonDocument::Compact);
|
|
||||||
|
|
||||||
this->apismTcpRequestResponseClient->sendData(data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void ApismClient::sendSelfTest() {
|
|
||||||
qDebug() << "SENDING APISM-SELF-TEST";
|
|
||||||
this->currentRequest = ISMAS::REQUEST::SELF;
|
|
||||||
QByteArray data = "#M=APISM#C=REQ_SELF#J={}";
|
|
||||||
this->apismTcpRequestResponseClient->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void ApismClient::sendMininformPingRequest()
|
|
||||||
{
|
|
||||||
this->currentRequest = ISMAS::REQUEST::PING;
|
|
||||||
|
|
||||||
QByteArray data = "#M=APISM#C=REQ_Ping#J={\"281\":\"PING\"}";
|
|
||||||
|
|
||||||
this->apismTcpRequestResponseClient->sendData(data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void ApismClient::onReceivedResponse(QByteArray response) {
|
|
||||||
|
|
||||||
qCritical() << "RECEIVED ------> " << response;
|
|
||||||
|
|
||||||
if (this->currentRequest == ISMAS::REQUEST::NO_REQUEST &&
|
|
||||||
response == "RECORD SAVED") { // sent by APISM to indicate that record
|
|
||||||
return; // has been saved in DB
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the root object
|
|
||||||
QJsonParseError jsonParseError;
|
|
||||||
QJsonDocument responseDoc = QJsonDocument::fromJson(response, &jsonParseError);
|
|
||||||
|
|
||||||
if (jsonParseError.error != QJsonParseError::NoError) {
|
|
||||||
qCritical() << "ApismClient::onReceivedResponse() response is no json data:";
|
|
||||||
qCritical() << " Error: " << jsonParseError.errorString();
|
|
||||||
this->handleISMASResponseError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject rootObject = responseDoc.object();
|
|
||||||
QStringList rootObjectKeys = rootObject.keys();
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
qDebug() << "ApismClient::onReceivedResponse(): objects: " << rootObjectKeys;
|
|
||||||
// results to:
|
|
||||||
// ApismClient::onReceivedResponse(): objects: ("REQ_START#60044_Response", "Response")
|
|
||||||
|
|
||||||
|
|
||||||
if(rootObjectKeys.indexOf(QRegularExpression("^REQ_START.*")) >= 0) {
|
|
||||||
this->private_handleMininformStartResponse(rootObject["Response"].toObject());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(rootObjectKeys.indexOf(QRegularExpression("^REQ_STOP.*")) >= 0) {
|
|
||||||
this->private_handleMininformStopResponse(rootObject["Response"].toObject());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(rootObjectKeys.indexOf(QRegularExpression("^REQ_SELF.*")) >= 0) {
|
|
||||||
this->private_handleReqSelfResponse(rootObject["Response"].toObject());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(rootObjectKeys.indexOf(QRegularExpression("^REQ_PING.*")) >= 0) {
|
|
||||||
this->private_handleReqPingResponse(rootObject["PING"].toObject());
|
|
||||||
} else
|
|
||||||
if(rootObjectKeys.indexOf(QRegularExpression("^REQ_ISMASPARAMETER.*")) >= 0) {
|
|
||||||
this->private_handleIsmasParameterResponse(rootObject);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qCritical() << "ApismClient::onReceivedResponse() for unknown Request: ";
|
|
||||||
qCritical() << " currentRequestName: " << currentRequest;
|
|
||||||
qCritical() << " rootObject.keys(): " << rootObjectKeys;
|
|
||||||
this->handleISMASResponseError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::handleISMASResponseError()
|
|
||||||
{
|
|
||||||
switch (this->currentRequest) {
|
|
||||||
case ISMAS::REQUEST::NO_REQUEST:
|
|
||||||
qCritical() << "ApismClient::onReceivedResponse() for unknown Request: " << currentRequest;
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::START:
|
|
||||||
emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::STOP:
|
|
||||||
emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::PING:
|
|
||||||
emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::SELF:
|
|
||||||
emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::ISMAS_PARAMETER:
|
|
||||||
// TODO
|
|
||||||
// emit
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
{\r\n \"REQ_START#53365_Response\": {\r\n \"Aknoledge\": \"OK\"\r\n },
|
|
||||||
\r\n \"Response\": {\r\n \"Result\": \"ERR:Ung<6E>ltiger Datums-String: \"\r\n }\r\n}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
: ISMAS received: "{\r\n \"REQ_PING#30844_Response\": {\r\n \"Aknoledge\": \"OK\"\r\n },
|
|
||||||
"PING": { "IsAviable": "TRUE" }
|
|
||||||
}"
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ApismClient::onSendClientResponseTimeout()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::onRequestResponseClientResponseTimeout()
|
|
||||||
{
|
|
||||||
switch (this->currentRequest) {
|
|
||||||
case ISMAS::REQUEST::NO_REQUEST:
|
|
||||||
qCritical() << "ApismClient::onRequestResponseClientResponseTimeout() for unknown Request: " << currentRequest;
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::START:
|
|
||||||
emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::STOP:
|
|
||||||
emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::PING:
|
|
||||||
emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::SELF:
|
|
||||||
emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject());
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::ISMAS_PARAMETER:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->currentRequest = ISMAS::REQUEST::NO_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApismClient::private_handleMininformStartResponse(QJsonObject response)
|
|
||||||
{
|
|
||||||
emit this->sendMininformStartResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::private_handleMininformStopResponse(QJsonObject response)
|
|
||||||
{
|
|
||||||
emit this->sendMininformStopResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::private_handleReqSelfResponse(QJsonObject response)
|
|
||||||
{
|
|
||||||
emit this->sendReqSelfResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::private_handleReqPingResponse(QJsonObject response)
|
|
||||||
{
|
|
||||||
emit this->sendMininformPingResponse(nsApismInterface::RESULT_STATE::SUCCESS, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismClient::private_handleIsmasParameterResponse(QJsonObject response) {
|
|
||||||
emit this->ismasResponseAvailable(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************************
|
|
||||||
* operators
|
|
||||||
*/
|
|
||||||
QDebug operator<< (QDebug debug, ISMAS::REQUEST request)
|
|
||||||
{
|
|
||||||
switch(request) {
|
|
||||||
case ISMAS::REQUEST::NO_REQUEST:
|
|
||||||
debug << QString("ISMAS::REQUEST::NO_REQUEST");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::START:
|
|
||||||
debug << QString("ISMAS::REQUEST::START");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::STOP:
|
|
||||||
debug << QString("ISMAS::REQUEST::STOP");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::PING:
|
|
||||||
debug << QString("ISMAS::REQUEST::PING");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::SELF:
|
|
||||||
debug << QString("ISMAS::REQUEST::SELF");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::ISMAS_PARAMETER:
|
|
||||||
debug << QString("ISMAS::REQUEST::ISMASPARAMETER");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString& operator<< (QString& str, ISMAS::REQUEST request)
|
|
||||||
{
|
|
||||||
switch(request) {
|
|
||||||
case ISMAS::REQUEST::NO_REQUEST:
|
|
||||||
str = QString("ISMAS::REQUEST::NO_REQUEST");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::START:
|
|
||||||
str = QString("ISMAS::REQUEST::START");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::STOP:
|
|
||||||
str = QString("ISMAS::REQUEST::STOP");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::PING:
|
|
||||||
str = QString("ISMAS::REQUEST::PING");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::SELF:
|
|
||||||
str = QString("ISMAS::REQUEST::SELF");
|
|
||||||
break;
|
|
||||||
case ISMAS::REQUEST::ISMAS_PARAMETER:
|
|
||||||
str = QString("ISMAS::REQUEST::ISMASPARAMETER");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
|||||||
#ifndef APISM_CLIENT_H_INCLUDED
|
|
||||||
#define APISM_CLIENT_H_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "ismas_data.h"
|
|
||||||
#include "apism_tcp_client.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QAbstractSocket>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QJsonValue>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, ISMAS::REQUEST request);
|
|
||||||
QString& operator<<(QString& str, ISMAS::REQUEST request);
|
|
||||||
|
|
||||||
namespace nsApismInterface {
|
|
||||||
|
|
||||||
enum class RESULT_STATE : quint8 {
|
|
||||||
SUCCESS = 1,
|
|
||||||
ERROR_BACKEND = 2, // error from backand (e.g. backend replies with error)
|
|
||||||
ERROR_NETWORK = 3, // error from network (e.g. host not available)
|
|
||||||
ERROR_TIMEOUT = 4, // the operation timed out
|
|
||||||
ERROR_PROCESS = 5, // internal plugin error (e.g. bug in implementation)
|
|
||||||
ERROR_RETRY = 6, // retry operation
|
|
||||||
INFO = 7
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class VendingData;
|
|
||||||
class ATBHMIconfig;
|
|
||||||
class PersistentData;
|
|
||||||
class ATBMachineEvent;
|
|
||||||
class ApismClient : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ApismClient(QObject *eventReceiver, ATBHMIconfig *config, PersistentData *persistentData, QObject *parent = 0);
|
|
||||||
~ApismClient();
|
|
||||||
|
|
||||||
quint32 getLastError();
|
|
||||||
const QString & getLastErrorDescription();
|
|
||||||
|
|
||||||
ApismTcpClient* getApismTcpSendClient() { return apismTcpSendClient; }
|
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void sendSelfTest();
|
|
||||||
void sendTransaction(const VendingData* vendingData);
|
|
||||||
// void sendAccount(const QHash<QString, QVariant> &accountDataHash);
|
|
||||||
//void sendEvent(const ATBMachineEvent* machineEvent);
|
|
||||||
|
|
||||||
void sendState(const QString & state, const QString & msg);
|
|
||||||
void emulateUpdatesAvailable(QString const &msg);
|
|
||||||
void onSendCmdSendVersionToIsmas(QString);
|
|
||||||
void onSendCmdEventToIsmas(QString);
|
|
||||||
void requestAvailableIsmasUpdates();
|
|
||||||
|
|
||||||
|
|
||||||
//void sendMininformStartRequest(const VendingData* vendingData);
|
|
||||||
//void sendMininformStopRequest(const VendingData* vendingData);
|
|
||||||
//void sendMininformPingRequest();
|
|
||||||
|
|
||||||
void restartApism();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
// public signals:
|
|
||||||
void sendTransactionRespones(nsApismInterface::RESULT_STATE result);
|
|
||||||
void sendAccountResponse(nsApismInterface::RESULT_STATE result);
|
|
||||||
|
|
||||||
|
|
||||||
void sendMininformStartResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
|
|
||||||
void sendMininformStopResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
|
|
||||||
void sendMininformPingResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
|
|
||||||
void sendReqSelfResponse(nsApismInterface::RESULT_STATE result, QJsonObject response);
|
|
||||||
|
|
||||||
void ismasResponseAvailable(QJsonObject ismasResponse);
|
|
||||||
void sendCmdSendVersionToIsmas(QString);
|
|
||||||
void sendCmdEventToIsmas(QString);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
// void onSocketError(QAbstractSocket::SocketError socketError);
|
|
||||||
|
|
||||||
void onReceivedResponse(QByteArray response);
|
|
||||||
|
|
||||||
void onSendClientResponseTimeout();
|
|
||||||
void onRequestResponseClientResponseTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QObject *healthEventReceiver;
|
|
||||||
ATBHMIconfig *m_config;
|
|
||||||
|
|
||||||
PersistentData *persistentData;
|
|
||||||
|
|
||||||
ApismTcpClient* apismTcpSendClient;
|
|
||||||
ApismTcpClient* apismTcpRequestResponseClient;
|
|
||||||
|
|
||||||
quint32 lastError;
|
|
||||||
QString lastErrorDescription;
|
|
||||||
|
|
||||||
QString currentRequestUid;
|
|
||||||
ISMAS::REQUEST currentRequest;
|
|
||||||
|
|
||||||
|
|
||||||
void private_handleMininformStartResponse(QJsonObject response);
|
|
||||||
void private_handleMininformStopResponse(QJsonObject response);
|
|
||||||
void private_handlePingResponse(QJsonObject response);
|
|
||||||
void private_handleReqSelfResponse(QJsonObject response);
|
|
||||||
void private_handleReqPingResponse(QJsonObject response);
|
|
||||||
void private_handleIsmasParameterResponse(QJsonObject response);
|
|
||||||
|
|
||||||
void handleISMASResponseError();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
|
|
||||||
|
|
||||||
#endif // APISM_CLIENT_H_INCLUDED
|
|
@ -1,172 +0,0 @@
|
|||||||
#include "apism_tcp_client.h"
|
|
||||||
|
|
||||||
#include <QHostAddress>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
|
|
||||||
ApismTcpClient::ApismTcpClient(const QString & hostname,
|
|
||||||
const QString & port,
|
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, hostname(hostname)
|
|
||||||
, port(port)
|
|
||||||
, responseTimerTimeoutCounter(0)
|
|
||||||
{
|
|
||||||
this->responseTimeoutTimer = new QTimer(this);
|
|
||||||
this->responseTimeoutTimer->setInterval(10000);
|
|
||||||
this->responseTimeoutTimer->setSingleShot(true);
|
|
||||||
|
|
||||||
connect(this->responseTimeoutTimer, SIGNAL(timeout()), this, SLOT(onResponseTimeoutTimerTimeout()));
|
|
||||||
|
|
||||||
socket = new QTcpSocket(this);
|
|
||||||
connect(socket, SIGNAL(connected()), this, SLOT(onSocketConnected()));
|
|
||||||
connect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
|
||||||
connect(socket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
|
|
||||||
connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(onSocketBytesWritten(qint64)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ApismTcpClient::connectToHost() {
|
|
||||||
qCritical() << "ApismTcpClient::connectToHost(this->" << hostname << ", " << port << ")";
|
|
||||||
int portNumber = this->port.toInt();
|
|
||||||
this->socket->connectToHost(QHostAddress(this->hostname), portNumber);
|
|
||||||
if (!socket->waitForConnected(10000)) {
|
|
||||||
qCritical() << "ERROR IN WAIT FOR CONNECTED" << socket->errorString();
|
|
||||||
} else {
|
|
||||||
qDebug() << "connected to" << hostname << ", " << port << ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::connectToHost(const QString & hostname, const QString & port)
|
|
||||||
{
|
|
||||||
qCritical() << "ApismTcpClient::connectToHost(" << hostname << ", " << port << ")";
|
|
||||||
|
|
||||||
int portNumber = port.toInt();
|
|
||||||
socket->connectToHost(hostname, portNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::closeConnection()
|
|
||||||
{
|
|
||||||
socket->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApismTcpClient::isConnected()
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
QAbstractSocket::SocketState socketState = socket->state();
|
|
||||||
|
|
||||||
switch (socketState) {
|
|
||||||
case QAbstractSocket::UnconnectedState:
|
|
||||||
/* FALLTHRU */
|
|
||||||
case QAbstractSocket::HostLookupState:
|
|
||||||
/* FALLTHRU */
|
|
||||||
case QAbstractSocket::ConnectingState:
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
case QAbstractSocket::ConnectedState:
|
|
||||||
/* FALLTHRU */
|
|
||||||
case QAbstractSocket::BoundState:
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
case QAbstractSocket::ClosingState:
|
|
||||||
/* FALLTHRU */
|
|
||||||
case QAbstractSocket::ListeningState:
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ApismTcpClient::sendData(const QByteArray & message) {
|
|
||||||
qDebug() << "ApismTcpClient::send: " << message;
|
|
||||||
|
|
||||||
this->sendQueue.enqueue(message);
|
|
||||||
|
|
||||||
if (this->isConnected()) {
|
|
||||||
qCritical() << "ApismTcpClient::send: connected, send" << message;
|
|
||||||
this->private_sendData();
|
|
||||||
} else {
|
|
||||||
qCritical() << "ApismTcpClient::send: not connected, connect";
|
|
||||||
this->connectToHost();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ApismTcpClient::private_sendData
|
|
||||||
*
|
|
||||||
* Precondition is that queue is not empty.
|
|
||||||
*/
|
|
||||||
void ApismTcpClient::private_sendData()
|
|
||||||
{
|
|
||||||
// take message from queue
|
|
||||||
QByteArray ba = this->sendQueue.dequeue();
|
|
||||||
|
|
||||||
qDebug() << "ApismTcpClient::send: " << QString(ba);
|
|
||||||
|
|
||||||
socket->write(ba);
|
|
||||||
socket->flush();
|
|
||||||
|
|
||||||
// start timeoutTimer
|
|
||||||
this->responseTimeoutTimer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::onSocketConnected()
|
|
||||||
{
|
|
||||||
qInfo() << "ApismTcpClient: Connected!";
|
|
||||||
|
|
||||||
if (this->sendQueue.size() > 0) {
|
|
||||||
this->private_sendData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::onSocketDisconnected()
|
|
||||||
{
|
|
||||||
qDebug() << "ApismTcpClient: Disconnected!";
|
|
||||||
qDebug() << " -> SocketErrorString: " << socket->errorString();
|
|
||||||
|
|
||||||
if (this->sendQueue.size() > 0) {
|
|
||||||
this->connectToHost();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::onSocketBytesWritten(qint64 bytes)
|
|
||||||
{
|
|
||||||
Q_UNUSED(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApismTcpClient::onSocketReadyRead()
|
|
||||||
{
|
|
||||||
QByteArray readData;
|
|
||||||
|
|
||||||
// stop timeoutTimer
|
|
||||||
this->responseTimeoutTimer->stop();
|
|
||||||
|
|
||||||
readData = socket->readAll();
|
|
||||||
|
|
||||||
qDebug() << "ISMAS received: " << QString(readData);
|
|
||||||
|
|
||||||
emit this->receivedData(readData);
|
|
||||||
//QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
this->socket->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ApismTcpClient::onResponseTimeoutTimerTimeout()
|
|
||||||
{
|
|
||||||
if (this->sendQueue.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit this->responseTimeout();
|
|
||||||
|
|
||||||
qCritical() << "ApismTcpClient::onResponseTimeoutTimerTimeout() --> skip this message, send next command, if available.";
|
|
||||||
|
|
||||||
// Try next command
|
|
||||||
this->sendQueue.removeFirst();
|
|
||||||
if (this->sendQueue.size() > 0) this->private_sendData();
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
#ifndef APISMTCPCLIENT_H
|
|
||||||
#define APISMTCPCLIENT_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <QAbstractSocket>
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QQueue>
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
class ApismTcpClient : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ApismTcpClient(const QString & hostname, const QString & port, QObject *parent = nullptr);
|
|
||||||
bool isConnected();
|
|
||||||
|
|
||||||
void connectToHost();
|
|
||||||
void connectToHost(const QString & hostname, const QString & port);
|
|
||||||
|
|
||||||
// socket is implicitely closed by APISM
|
|
||||||
void closeConnection();
|
|
||||||
|
|
||||||
void sendData(const QByteArray & message);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
// socket interface
|
|
||||||
void onSocketConnected();
|
|
||||||
void onSocketDisconnected();
|
|
||||||
void onSocketBytesWritten(qint64 bytes);
|
|
||||||
void onSocketReadyRead();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void receivedData(QByteArray response);
|
|
||||||
|
|
||||||
void responseTimeout();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QTcpSocket *socket;
|
|
||||||
|
|
||||||
QQueue<QByteArray> sendQueue;
|
|
||||||
|
|
||||||
|
|
||||||
QString hostname;
|
|
||||||
QString port;
|
|
||||||
|
|
||||||
QTimer *responseTimeoutTimer;
|
|
||||||
quint8 responseTimerTimeoutCounter;
|
|
||||||
|
|
||||||
|
|
||||||
void private_sendData();
|
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onResponseTimeoutTimerTimeout();
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // APISMTCPCLIENT_H
|
|
@ -1,6 +1,7 @@
|
|||||||
#include "git_client.h"
|
#include "git_client.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "worker.h"
|
#include "worker.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -22,67 +23,6 @@ GitClient::GitClient(QString const &customerNrStr,
|
|||||||
if (!m_worker) {
|
if (!m_worker) {
|
||||||
qCritical() << "ERROR CASTING PARENT TO WORKER FAILED";
|
qCritical() << "ERROR CASTING PARENT TO WORKER FAILED";
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(this, SIGNAL(ismasUpdatesAvailable()),
|
|
||||||
this, SLOT(onIsmasUpdatesAvailable()), Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GitClient::onIsmasUpdatesAvailable() {
|
|
||||||
if (QDir(m_customerRepository).exists()) {
|
|
||||||
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST,
|
|
||||||
QString("FETCHING OF ") + m_repositoryPath +
|
|
||||||
QString(" INTO ") + m_customerRepository);
|
|
||||||
|
|
||||||
std::optional<QString> changes = gitFetch();
|
|
||||||
|
|
||||||
if (changes) {
|
|
||||||
std::optional<QStringList> changedFileNames = gitDiff(changes.value());
|
|
||||||
if (changedFileNames) {
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS,
|
|
||||||
QString("FETCHED NEW FILES ") +
|
|
||||||
changedFileNames.value().join(",") +
|
|
||||||
QString(" INTO ") + m_customerRepository);
|
|
||||||
if (gitPull()) {
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::GIT_PULL_UPDATES_SUCCESS,
|
|
||||||
QString("PULL NEW FILES ") +
|
|
||||||
changedFileNames.value().join(",") +
|
|
||||||
QString(" INTO ") + m_customerRepository);
|
|
||||||
|
|
||||||
emit m_worker->handleChangedFiles(changedFileNames.value());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
qCritical() << UpdateStatus(UPDATE_STATUS::GIT_PULL_UPDATES_FAILURE,
|
|
||||||
QString("PULLING NEW FILES ") +
|
|
||||||
changedFileNames.value().join(",") +
|
|
||||||
QString(" INTO ") + m_customerRepository + " FAILED");
|
|
||||||
|
|
||||||
emit m_worker->terminateUpdateProcess();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qCritical() << "NO CHANGES IN" << m_repositoryPath
|
|
||||||
<< "(" << m_customerRepository << ")";
|
|
||||||
emit m_worker->finishUpdateProcess(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qCritical() << UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
|
||||||
QString("NO CHANGES IN ") + m_repositoryPath +
|
|
||||||
QString(" (%1)").arg(m_customerRepository));
|
|
||||||
|
|
||||||
emit m_worker->finishUpdateProcess(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (gitCloneAndCheckoutBranch()) {
|
|
||||||
qInfo() << "CLONED" << m_repositoryPath
|
|
||||||
<< "AND CHECKED OUT INTO" << m_customerRepository;
|
|
||||||
} else {
|
|
||||||
qCritical() << "ERROR CLONING " << m_repositoryPath
|
|
||||||
<< "AND/OR CHECKING OUT INTO" << m_customerRepository;
|
|
||||||
emit m_worker->terminateUpdateProcess();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::gitCloneCustomerRepository() {
|
bool GitClient::gitCloneCustomerRepository() {
|
||||||
@ -128,10 +68,31 @@ bool GitClient::copyGitConfigFromMaster() { // only allowed when called in
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitClient::gitCheckoutBranch() {
|
QStringList GitClient::gitBranchNames() {
|
||||||
|
// git config --global pager.branch false
|
||||||
|
QStringList bNames;
|
||||||
if (QDir(m_customerRepository).exists()) {
|
if (QDir(m_customerRepository).exists()) {
|
||||||
|
QString gitCommand("git branch -a");
|
||||||
|
Command c(gitCommand);
|
||||||
|
if (c.execute(m_customerRepository)) {
|
||||||
|
QString const result = c.getCommandResult();
|
||||||
|
return result.split('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GitClient::gitCheckoutBranch() {
|
||||||
|
// TODO: nachsehen, ob der Branch ueberhaupt existiert
|
||||||
|
|
||||||
|
if (QDir(m_customerRepository).exists()) {
|
||||||
|
int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
|
||||||
|
m_branchName = (zoneNr != 0)
|
||||||
|
? QString("zg1/zone%1").arg(zoneNr) : "master";
|
||||||
|
|
||||||
QString gitCommand("git checkout ");
|
QString gitCommand("git checkout ");
|
||||||
gitCommand += m_branchName;
|
gitCommand += m_branchName;
|
||||||
|
|
||||||
Command c(gitCommand);
|
Command c(gitCommand);
|
||||||
return c.execute(m_customerRepository); // execute command in customerRepo
|
return c.execute(m_customerRepository); // execute command in customerRepo
|
||||||
}
|
}
|
||||||
@ -146,11 +107,13 @@ bool GitClient::gitCloneAndCheckoutBranch() {
|
|||||||
if (gitCheckoutBranch()) {
|
if (gitCheckoutBranch()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
m_worker->terminateUpdateProcess();
|
// TODO
|
||||||
|
// m_worker->terminateUpdateProcess();
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
} else {
|
} else {
|
||||||
m_worker->terminateUpdateProcess();
|
// TODO
|
||||||
|
//m_worker->terminateUpdateProcess();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -201,12 +164,18 @@ std::optional<QStringList> GitClient::gitDiff(QString const &commits) {
|
|||||||
*/
|
*/
|
||||||
std::optional<QString> GitClient::gitFetch() {
|
std::optional<QString> GitClient::gitFetch() {
|
||||||
if (QDir(m_customerRepository).exists()) {
|
if (QDir(m_customerRepository).exists()) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
UpdateStatus status (UPDATE_STATUS::GIT_FETCH_UPDATES, "GIT FETCH UPDATES");
|
||||||
|
qInfo() << status;
|
||||||
|
|
||||||
|
//emit m_worker->sendCmdEventToIsmas(
|
||||||
|
// m_worker->getIsmasClient().updateOfPSAContinues(
|
||||||
|
// "GIT FETCH UPDATES", status.m_statusDescription));
|
||||||
|
|
||||||
Command c("git fetch");
|
Command c("git fetch");
|
||||||
if (c.execute(m_customerRepository)) {
|
if (c.execute(m_customerRepository)) {
|
||||||
QString const s = c.getCommandResult().trimmed();
|
QString const s = c.getCommandResult().trimmed();
|
||||||
|
|
||||||
qCritical() << "GIT RESULT" << s;
|
|
||||||
|
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
QStringList lines = Update::split(s, '\n');
|
QStringList lines = Update::split(s, '\n');
|
||||||
if (!lines.empty()) {
|
if (!lines.empty()) {
|
||||||
@ -215,6 +184,15 @@ std::optional<QString> GitClient::gitFetch() {
|
|||||||
QRegularExpressionMatch match = re.match(lines.last());
|
QRegularExpressionMatch match = re.match(lines.last());
|
||||||
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
|
||||||
|
// TODO
|
||||||
|
status = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_SUCCESS,
|
||||||
|
QString("GIT SUCCESSFULLY FETCHED ") + m_customerRepository);
|
||||||
|
qInfo() << status;
|
||||||
|
|
||||||
|
//emit m_worker->sendCmdEventToIsmas(
|
||||||
|
// m_worker->getIsmasClient().updateOfPSAContinues(
|
||||||
|
// "GIT_FETCH_UPDATES SUCCESS", status.m_statusDescription));
|
||||||
|
|
||||||
return match.captured(2);
|
return match.captured(2);
|
||||||
} else {
|
} else {
|
||||||
qCritical() << "ERROR WRONG CAPTURE COUNT FOR 'GIT FETCH'" << re.captureCount();
|
qCritical() << "ERROR WRONG CAPTURE COUNT FOR 'GIT FETCH'" << re.captureCount();
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
#define GIT_CLIENT_H_INCLUDED
|
#define GIT_CLIENT_H_INCLUDED
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QStringList>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "process/command.h"
|
#include "process/command.h"
|
||||||
|
#include "ismas/ismas_client.h"
|
||||||
|
|
||||||
class Worker;
|
class Worker;
|
||||||
class GitClient : public QObject {
|
class GitClient : public QObject {
|
||||||
@ -14,7 +16,7 @@ class GitClient : public QObject {
|
|||||||
QString const m_repositoryPath;
|
QString const m_repositoryPath;
|
||||||
QString const m_customerNr;
|
QString const m_customerNr;
|
||||||
QString const m_workingDirectory;
|
QString const m_workingDirectory;
|
||||||
QString const m_branchName;
|
QString m_branchName;
|
||||||
QString const m_customerRepository;
|
QString const m_customerRepository;
|
||||||
|
|
||||||
bool copyGitConfigFromMaster();
|
bool copyGitConfigFromMaster();
|
||||||
@ -28,6 +30,7 @@ class GitClient : public QObject {
|
|||||||
|
|
||||||
bool gitCloneCustomerRepository();
|
bool gitCloneCustomerRepository();
|
||||||
bool gitCheckoutBranch();
|
bool gitCheckoutBranch();
|
||||||
|
QStringList gitBranchNames();
|
||||||
|
|
||||||
QString const workingDirectory() const { return m_workingDirectory; }
|
QString const workingDirectory() const { return m_workingDirectory; }
|
||||||
QString workingDirectory() { return m_workingDirectory; }
|
QString workingDirectory() { return m_workingDirectory; }
|
||||||
@ -50,13 +53,6 @@ class GitClient : public QObject {
|
|||||||
QString gitBlob(QString fileName);
|
QString gitBlob(QString fileName);
|
||||||
QString gitCommitForBlob(QString blob);
|
QString gitCommitForBlob(QString blob);
|
||||||
bool gitIsFileTracked(QString file2name);
|
bool gitIsFileTracked(QString file2name);
|
||||||
|
|
||||||
signals:
|
|
||||||
void ismasUpdatesAvailable();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onIsmasUpdatesAvailable();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GIT_CLIENT_H_INCLUDED
|
#endif // GIT_CLIENT_H_INCLUDED
|
||||||
|
@ -3,6 +3,24 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <arpa/inet.h> // inet_addr()
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h> // bzero()
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h> // read(), write(), close()
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
# $1: EVENT: U0001 update finished: 100%
|
# $1: EVENT: U0001 update finished: 100%
|
||||||
# U0002 reset TRG
|
# U0002 reset TRG
|
||||||
@ -24,6 +42,208 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
void IsmasClient::printDebugMessage(int port,
|
||||||
|
QString const &clientIP,
|
||||||
|
int clientPort,
|
||||||
|
QString const &message) {
|
||||||
|
qDebug().noquote()
|
||||||
|
<< "\n"
|
||||||
|
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||||
|
<< "hostname ........" << "127.0.0.1" << "\n"
|
||||||
|
<< "port ............" << port << "\n"
|
||||||
|
<< "local address ..." << clientIP << "\n"
|
||||||
|
<< "local port ......" << clientPort << "\n"
|
||||||
|
<< message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsmasClient::printInfoMessage(int port,
|
||||||
|
QString const &clientIP,
|
||||||
|
int clientPort,
|
||||||
|
QString const &message) {
|
||||||
|
qInfo().noquote()
|
||||||
|
<< "\n"
|
||||||
|
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||||
|
<< "hostname ........" << "127.0.0.1" << "\n"
|
||||||
|
<< "port ............" << port << "\n"
|
||||||
|
<< "local address ..." << clientIP << "\n"
|
||||||
|
<< "local port ......" << clientPort << "\n"
|
||||||
|
<< message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsmasClient::printErrorMessage(int port,
|
||||||
|
QString const &clientIP,
|
||||||
|
int clientPort,
|
||||||
|
QString const &message) {
|
||||||
|
qCritical().noquote()
|
||||||
|
<< "\n"
|
||||||
|
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||||
|
<< "hostname ........" << "127.0.0.1" << "\n"
|
||||||
|
<< "port ............" << port << "\n"
|
||||||
|
<< "local address ..." << clientIP << "\n"
|
||||||
|
<< "local port ......" << clientPort << "\n"
|
||||||
|
<< message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QString>
|
||||||
|
IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
|
||||||
|
|
||||||
|
qInfo() << "REQUEST" << request;
|
||||||
|
|
||||||
|
int sockfd;
|
||||||
|
int r;
|
||||||
|
errno = 0;
|
||||||
|
// socket create and verification
|
||||||
|
if ((sockfd = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||||
|
qCritical().noquote()
|
||||||
|
<< "\n"
|
||||||
|
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||||
|
<< "SOCKET CREATION FAILED (" << strerror(errno) << ")";
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in servAddr;
|
||||||
|
bzero(&servAddr, sizeof(servAddr));
|
||||||
|
// assign IP, PORT
|
||||||
|
servAddr.sin_family = AF_INET;
|
||||||
|
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
|
||||||
|
servAddr.sin_port = htons(port);
|
||||||
|
// connect the client socket to server socket
|
||||||
|
if ((r = ::connect(sockfd, (struct sockaddr *)(&servAddr), sizeof(servAddr))) != 0) {
|
||||||
|
qCritical().noquote()
|
||||||
|
<< "\n"
|
||||||
|
<< "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n"
|
||||||
|
<< "CONNECTION WITH SERVER FAILED (" << strerror(r) << ")";
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in clientAddr;
|
||||||
|
bzero(&clientAddr, sizeof(clientAddr));
|
||||||
|
socklen_t sockLen = sizeof(clientAddr);
|
||||||
|
|
||||||
|
char clientIP[16];
|
||||||
|
bzero(&clientIP, sizeof(clientIP));
|
||||||
|
getsockname(sockfd, (struct sockaddr *)(&clientAddr), &sockLen);
|
||||||
|
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, sizeof(clientIP));
|
||||||
|
unsigned int clientPort = ntohs(clientAddr.sin_port);
|
||||||
|
|
||||||
|
printDebugMessage(port, clientIP, clientPort, QString("CONNECTED TO SERVER"));
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = 10; /* 10 secs timeout for read and write */
|
||||||
|
|
||||||
|
struct linger so_linger;
|
||||||
|
so_linger.l_onoff = 1;
|
||||||
|
so_linger.l_linger = 0;
|
||||||
|
|
||||||
|
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
|
||||||
|
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||||
|
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||||
|
int flag = 1;
|
||||||
|
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
|
||||||
|
|
||||||
|
static char buf[1024*8];
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
int const bytesToWrite = strlen(request.toStdString().c_str());
|
||||||
|
strncpy(buf, request.toStdString().c_str(), sizeof(buf)-1);
|
||||||
|
|
||||||
|
int bytesWritten = 0;
|
||||||
|
while (bytesWritten < bytesToWrite) {
|
||||||
|
int n = ::sendto(sockfd, buf+bytesWritten, bytesToWrite-bytesWritten, 0, NULL, 0);
|
||||||
|
if (n >= 0) {
|
||||||
|
bytesWritten += n;
|
||||||
|
} else {
|
||||||
|
if (errno == EWOULDBLOCK) {
|
||||||
|
printErrorMessage(port, clientIP, clientPort,
|
||||||
|
QString("TIMEOUT (") + strerror(errno) + ")");
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
} else
|
||||||
|
if (errno == EINTR) {
|
||||||
|
printErrorMessage(port, clientIP, clientPort,
|
||||||
|
QString("INTERRUPTED BY SIGNAL (1) (") + strerror(errno) + ")");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO NOT USE SHUTDOWN! APISM CAN NOT COPE WITH IT
|
||||||
|
// errno = 0;
|
||||||
|
// if (shutdown(sockfd, SHUT_WR) < 0) {
|
||||||
|
// printErrorMessage(port, clientIP, clientPort,
|
||||||
|
// QString("CANNOT CLOSE WRITING END (") + strerror(errno) + ")");
|
||||||
|
// }
|
||||||
|
|
||||||
|
printInfoMessage(port, clientIP, clientPort, QString("MESSAGE SENT ") + buf);
|
||||||
|
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
int bytesToRead = sizeof(buf)-1;
|
||||||
|
int bytesRead = 0;
|
||||||
|
while (bytesRead < bytesToRead) {
|
||||||
|
errno = 0;
|
||||||
|
int n = ::recvfrom(sockfd, buf+bytesRead, bytesToRead-bytesRead,
|
||||||
|
0, NULL, NULL);
|
||||||
|
if (n > 0) { //
|
||||||
|
bytesRead += n;
|
||||||
|
} else
|
||||||
|
if (n == 0) {
|
||||||
|
// The return value will be 0 when the peer has performed an orderly shutdown.
|
||||||
|
printErrorMessage(port, clientIP, clientPort,
|
||||||
|
QString("PEER CLOSED CONNECTION (") + strerror(errno) + ")");
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
} else
|
||||||
|
if (n < 0) {
|
||||||
|
if (errno == EWOULDBLOCK) {
|
||||||
|
printErrorMessage(port, clientIP, clientPort,
|
||||||
|
QString("TIMEOUT (") + strerror(errno) + ")");
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
if (errno == EINTR) {
|
||||||
|
printErrorMessage(port, clientIP, clientPort,
|
||||||
|
QString("INTERRUPTED BY SIGNAL (2) (") + strerror(errno) + ")");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printInfoMessage(port, clientIP, clientPort, QString("MESSAGE RECEIVED ") + buf);
|
||||||
|
QString response(buf);
|
||||||
|
|
||||||
|
if (int idx = response.indexOf("{\"error\":\"ISMAS is offline\"}")) {
|
||||||
|
response = response.mid(0, idx);
|
||||||
|
} else
|
||||||
|
if (response == "RECORD SAVED") {
|
||||||
|
printInfoMessage(port, clientIP, clientPort, "IGNORED 'RECORD SAVED' RESPONSE");
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument document(QJsonDocument::fromJson(response.toUtf8(), &parseError));
|
||||||
|
if (parseError.error == QJsonParseError::NoError) {
|
||||||
|
if (document.isObject()) { // done: received valid APISM response
|
||||||
|
printInfoMessage(port, clientIP, clientPort,
|
||||||
|
QString("VALID APISM RESPONSE .. \n") + response);
|
||||||
|
::close(sockfd);
|
||||||
|
return response;
|
||||||
|
} else {
|
||||||
|
printInfoMessage(port, clientIP, clientPort,
|
||||||
|
QString("CORRUPTED RESPONSE ") + response);
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printDebugMessage(port, clientIP, clientPort,
|
||||||
|
QString("PARSE ERROR ") + response + " " + parseError.errorString());
|
||||||
|
::close(sockfd);
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
QString IsmasClient::updateNewsToIsmas(char const *event,
|
QString IsmasClient::updateNewsToIsmas(char const *event,
|
||||||
int percent,
|
int percent,
|
||||||
int resultCode,
|
int resultCode,
|
||||||
@ -53,6 +273,54 @@ QString IsmasClient::updateNewsToIsmas(char const *event,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::errorBackendNotConnected(QString const &info,
|
||||||
|
QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0003",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::INSTALL_ERROR,
|
||||||
|
"CHECK BACKEND CONNECTIVITY",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::backendConnected(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"CHECK BACKEND CONNECTIVITY",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::execOpkgCommand(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"EXECUTE OPKG COMMAND",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::updateTriggerSet(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"CHECK UPDATE TRIGGER",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::errorUpdateTrigger(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0003",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::INSTALL_ERROR,
|
||||||
|
"CHECK UPDATE TRIGGER",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
||||||
//static int const constexpr SIZE = 4096*8;
|
//static int const constexpr SIZE = 4096*8;
|
||||||
static char buf[4096*2];
|
static char buf[4096*2];
|
||||||
@ -376,39 +644,101 @@ QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) {
|
|||||||
psa.pluginVersion.prmCalculatePriceConfigUi.toStdString().c_str(),
|
psa.pluginVersion.prmCalculatePriceConfigUi.toStdString().c_str(),
|
||||||
psa.pluginVersion.tcpZVT.toStdString().c_str());
|
psa.pluginVersion.tcpZVT.toStdString().c_str());
|
||||||
|
|
||||||
printf("buf=%s\n", buf);
|
qInfo() << buf;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::updateOfPSAContinues(QString currentStage,
|
||||||
QString IsmasClient::updateOfPSAActivated() {
|
QString currentStageInfo,
|
||||||
|
QString const &version) {
|
||||||
return updateNewsToIsmas("U0010",
|
return updateNewsToIsmas("U0010",
|
||||||
1,
|
m_progressInPercent,
|
||||||
0,
|
RESULT_CODE::SUCCESS,
|
||||||
"activated",
|
currentStage.toStdString().c_str(),
|
||||||
"detected WAIT state",
|
currentStageInfo.toStdString().c_str(),
|
||||||
"1.0.0");
|
version.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IsmasClient::updateOfPSASucceeded() {
|
QString IsmasClient::updateOfPSAStarted(QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"START",
|
||||||
|
"detected WAIT state: start update process",
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::checkoutBranch(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"BRANCH-CHECKOUT",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::cloneAndCheckoutCustomerRepository(QString const &info, QString const &version) { // clone and checkout customer repository
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"CLONE-CHECKOUT",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::gitFetch(QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0010",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"GIT-FETCH",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::errorGitFetch(int resultCode, QString const &info, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0003",
|
||||||
|
m_progressInPercent,
|
||||||
|
resultCode,
|
||||||
|
"GIT-FETCH-FAILED",
|
||||||
|
info.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::updateOfPSAActivated(QString const &version) { // sent even after success
|
||||||
|
m_progressInPercent = 0;
|
||||||
|
return updateNewsToIsmas("U0002",
|
||||||
|
m_progressInPercent,
|
||||||
|
RESULT_CODE::SUCCESS,
|
||||||
|
"UPDATE ACTIVATED",
|
||||||
|
"reset WAIT state",
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::updateOfPSASucceeded(QString const &version) {
|
||||||
|
m_progressInPercent = 0;
|
||||||
return updateNewsToIsmas("U0001",
|
return updateNewsToIsmas("U0001",
|
||||||
100,
|
m_progressInPercent,
|
||||||
0,
|
RESULT_CODE::SUCCESS,
|
||||||
"update_succeeded",
|
"UPDATE SUCCESS",
|
||||||
"",
|
"update process succeeded",
|
||||||
"1.0.0");
|
version.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IsmasClient::setUpdatesAvailable() {
|
QString IsmasClient::sanityCheckFailed(int resultCode, QString reason, QString const &version) {
|
||||||
return updateNewsToIsmas("U0099",
|
return updateNewsToIsmas("U0003",
|
||||||
10,
|
m_progressInPercent,
|
||||||
0,
|
resultCode,
|
||||||
"set_updates_available",
|
"SANITY-CHECK-FAILED",
|
||||||
"",
|
reason.toStdString().c_str(),
|
||||||
"");
|
version.toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString IsmasClient::updateOfPSAFailed(int resultCode, QString reason, QString const &version) {
|
||||||
|
return updateNewsToIsmas("U0003",
|
||||||
bool checkForAvailableUpdates();
|
m_progressInPercent,
|
||||||
|
resultCode,
|
||||||
|
"UPDATE ERROR",
|
||||||
|
reason.toStdString().c_str(),
|
||||||
|
version.toStdString().c_str());
|
||||||
|
}
|
||||||
|
@ -111,7 +111,28 @@ struct PSAInstalled {
|
|||||||
class IsmasClient : public QObject {
|
class IsmasClient : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
int m_progressInPercent;
|
||||||
public:
|
public:
|
||||||
|
explicit IsmasClient() : m_progressInPercent(1) {}
|
||||||
|
|
||||||
|
enum APISM {
|
||||||
|
DB_PORT = 7777,
|
||||||
|
DIRECT_PORT = 7778
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RESULT_CODE {
|
||||||
|
SUCCESS=0,
|
||||||
|
NO_UPDATE_NECESSARY=1,
|
||||||
|
BACKUP_FAILED=2,
|
||||||
|
WRONG_PACKAGE=3,
|
||||||
|
INSTALL_ERROR=4};
|
||||||
|
|
||||||
|
static std::optional<QString>
|
||||||
|
sendRequestReceiveResponse(int port, QString const &request);
|
||||||
|
|
||||||
|
int getProgressInPercent() const {return m_progressInPercent; }
|
||||||
|
void setProgressInPercent(int procent) { m_progressInPercent = procent; }
|
||||||
|
|
||||||
QString updateNewsToIsmas(char const *event,
|
QString updateNewsToIsmas(char const *event,
|
||||||
int percent,
|
int percent,
|
||||||
int resultCode,
|
int resultCode,
|
||||||
@ -119,12 +140,32 @@ public:
|
|||||||
char const *step_result,
|
char const *step_result,
|
||||||
char const *version);
|
char const *version);
|
||||||
|
|
||||||
QString updateOfPSAActivated();
|
QString updateOfPSAStarted(QString const &version = QString()); // start of update process
|
||||||
QString updateOfPSASucceeded();
|
QString cloneAndCheckoutCustomerRepository(QString const &info, QString const &version = QString()); // clone and checkout customer repository
|
||||||
|
QString checkoutBranch(QString const &info, QString const &version = QString()); // checkout branch
|
||||||
|
QString errorBackendNotConnected(QString const &info, QString const &version = QString()); // checkout branch
|
||||||
|
QString backendConnected(QString const &info, QString const &version = QString());
|
||||||
|
QString updateTriggerSet(QString const &info, QString const &version = QString());
|
||||||
|
QString errorUpdateTrigger(QString const &info, QString const &version = QString());
|
||||||
|
QString gitFetch(QString const &info, QString const &version = QString());
|
||||||
|
QString execOpkgCommand(QString const &info, QString const &version = QString());
|
||||||
|
QString errorGitFetch(int resultCode, QString const &info, QString const &version = QString());
|
||||||
|
QString updateOfPSAActivated(QString const &version = QString());
|
||||||
|
// and update accepted
|
||||||
|
QString updateOfPSASucceeded(QString const &version = QString()); // update process succeeded
|
||||||
|
QString updateOfPSAContinues(QString currentStage, QString currentStageInfo, QString const &version = QString());
|
||||||
|
QString updateOfPSAFailed(int resultCode, QString reason, QString const &version = QString());
|
||||||
|
QString sanityCheckFailed(int resultCode, QString reason, QString const &version = QString());
|
||||||
|
|
||||||
QString updateOfPSASendVersion(PSAInstalled const &psa);
|
QString updateOfPSASendVersion(PSAInstalled const &psa);
|
||||||
|
|
||||||
QString setUpdatesAvailable();
|
private:
|
||||||
bool checkForAvailableUpdates();
|
static void printDebugMessage(int port, QString const &clientIP, int clientPort,
|
||||||
|
QString const &message);
|
||||||
|
static void printInfoMessage(int port, QString const &clientIP, int clientPort,
|
||||||
|
QString const &message);
|
||||||
|
static void printErrorMessage(int port, QString const &clientIP, int clientPort,
|
||||||
|
QString const &message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ISMAS_CLIENT_H_INCLUDED
|
#endif // ISMAS_CLIENT_H_INCLUDED
|
||||||
|
23
main.cpp
23
main.cpp
@ -20,13 +20,15 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "git/git_client.h"
|
#include "git/git_client.h"
|
||||||
#include "ismas/ismas_client.h"
|
#include "ismas/ismas_client.h"
|
||||||
#include "apism/apism_client.h"
|
|
||||||
#include "worker_thread.h"
|
#include "worker_thread.h"
|
||||||
#include "worker.h"
|
#include "worker.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
@ -80,10 +82,6 @@ int main(int argc, char *argv[]) {
|
|||||||
workingDirectoryOption.setDefaultValue(workingDirectoryDefault);
|
workingDirectoryOption.setDefaultValue(workingDirectoryDefault);
|
||||||
parser.addOption(workingDirectoryOption);
|
parser.addOption(workingDirectoryOption);
|
||||||
|
|
||||||
QCommandLineOption maintenanceOption(QStringList() << "m" << "maintenance",
|
|
||||||
QCoreApplication::translate("main", "Maintenance mode for underlying script"));
|
|
||||||
parser.addOption(maintenanceOption);
|
|
||||||
|
|
||||||
QCommandLineOption dryRunOption(QStringList() << "d" << "dry-run",
|
QCommandLineOption dryRunOption(QStringList() << "d" << "dry-run",
|
||||||
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);
|
||||||
@ -101,7 +99,6 @@ int main(int argc, char *argv[]) {
|
|||||||
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 maintenanceMode = parser.isSet(maintenanceOption);
|
|
||||||
bool dryRun = parser.isSet(dryRunOption);
|
bool dryRun = parser.isSet(dryRunOption);
|
||||||
QString const rtPath = QCoreApplication::applicationDirPath();
|
QString const rtPath = QCoreApplication::applicationDirPath();
|
||||||
|
|
||||||
@ -118,7 +115,6 @@ int main(int argc, char *argv[]) {
|
|||||||
qInfo() << "plugInDir ........." << plugInDir;
|
qInfo() << "plugInDir ........." << plugInDir;
|
||||||
qInfo() << "plugInName ........" << plugInName;
|
qInfo() << "plugInName ........" << plugInName;
|
||||||
qInfo() << "workingDir ........" << workingDir;
|
qInfo() << "workingDir ........" << workingDir;
|
||||||
qInfo() << "maintenanceMode ..." << maintenanceMode;
|
|
||||||
qInfo() << "dryRun ............" << dryRun;
|
qInfo() << "dryRun ............" << dryRun;
|
||||||
|
|
||||||
// before loading the library, delete all possible shared memory segments
|
// before loading the library, delete all possible shared memory segments
|
||||||
@ -131,11 +127,9 @@ int main(int argc, char *argv[]) {
|
|||||||
hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
|
hwinf *hw = Update::loadDCPlugin(QDir(plugInDir), plugInName);
|
||||||
// hw->dc_autoRequest(false);
|
// hw->dc_autoRequest(false);
|
||||||
|
|
||||||
QString const update_ctrl_file = "/opt/app/tools/atbupdate/update_log.csv";
|
int machineNr = Utils::read1stLineOfFile("/etc/machine_nr");
|
||||||
|
int customerNr = Utils::read1stLineOfFile("/etc/cust_nr");
|
||||||
int machineNr = Worker::read1stLineOfFile("/etc/machine_nr");
|
int zoneNr = Utils::read1stLineOfFile("/etc/zone_nr");
|
||||||
int customerNr = Worker::read1stLineOfFile("/etc/cust_nr");
|
|
||||||
int zoneNr = Worker::read1stLineOfFile("/etc/zone_nr");
|
|
||||||
QString const branchName = (zoneNr != 0)
|
QString const branchName = (zoneNr != 0)
|
||||||
? QString("zg1/zone%1").arg(zoneNr) : "master";
|
? QString("zg1/zone%1").arg(zoneNr) : "master";
|
||||||
|
|
||||||
@ -148,8 +142,11 @@ int main(int argc, char *argv[]) {
|
|||||||
zoneNr,
|
zoneNr,
|
||||||
branchName,
|
branchName,
|
||||||
workingDir,
|
workingDir,
|
||||||
maintenanceMode,
|
|
||||||
dryRun);
|
dryRun);
|
||||||
|
|
||||||
|
MainWindow mw(&worker);
|
||||||
|
mw.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
|
||||||
|
mw.show();
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
97
mainwindow.cpp
Normal file
97
mainwindow.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "worker.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
MainWindow::MainWindow(Worker *worker, QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
, m_worker(worker)
|
||||||
|
, m_width(52) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->updateProgress->setRange(1, 100);
|
||||||
|
ui->updateProgress->reset();
|
||||||
|
|
||||||
|
m_startTimer = new QTimer(this);
|
||||||
|
connect(m_startTimer, SIGNAL(timeout()), ui->start, SLOT(click()));
|
||||||
|
m_startTimer->setSingleShot(true);
|
||||||
|
m_startTimer->start(5 * 1000);
|
||||||
|
|
||||||
|
m_exitTimer = new QTimer(this);
|
||||||
|
connect(m_exitTimer, SIGNAL(timeout()), ui->exit, SLOT(click()));
|
||||||
|
m_exitTimer->setSingleShot(true);
|
||||||
|
m_exitTimer->start(1800 * 1000);
|
||||||
|
|
||||||
|
connect(m_startTimer, SIGNAL(timeout()), ui->start, SLOT(click()));
|
||||||
|
connect(m_exitTimer, SIGNAL(timeout()), ui->exit, SLOT(click()));
|
||||||
|
connect(ui->start, SIGNAL(clicked()), m_worker, SLOT(update()));
|
||||||
|
connect(ui->exit, SIGNAL(clicked()), this, SLOT(onQuit()));
|
||||||
|
connect(m_worker, SIGNAL(stopStartTimer()), this, SLOT(onStopStartTimer()));
|
||||||
|
connect(m_worker, SIGNAL(restartExitTimer()), this, SLOT(onRestartExitTimer()));
|
||||||
|
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(setProgress(quint8)), this, SLOT(onSetProgress(quint8)));
|
||||||
|
|
||||||
|
QStringList lst;
|
||||||
|
QString start = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||||
|
lst << QString("Start: ") + start.leftJustified(m_width-10);
|
||||||
|
lst << QString("").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("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3);
|
||||||
|
lst << QString("").leftJustified(m_width-3, '=');
|
||||||
|
|
||||||
|
ui->updateStatus->setText(lst.join('\n'));
|
||||||
|
ui->updateStatus->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow() {
|
||||||
|
delete m_startTimer;
|
||||||
|
delete m_exitTimer;
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onStopStartTimer() {
|
||||||
|
m_startTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onRestartExitTimer() {
|
||||||
|
m_exitTimer->stop();
|
||||||
|
m_exitTimer->start(5 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onQuit() {
|
||||||
|
if (!m_worker->updateProcessRunning()) {
|
||||||
|
qApp->quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onSetProgress(quint8 v) {
|
||||||
|
ui->updateProgress->setValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onAppendText(QString text, QString suffix) {
|
||||||
|
QString editText = ui->updateStatus->toPlainText();
|
||||||
|
QStringList lines = editText.split('\n');
|
||||||
|
for (int i=0; i<lines.size(); ++i) {
|
||||||
|
qCritical() << lines.at(i);
|
||||||
|
}
|
||||||
|
if (!suffix.contains("[SUCCESS]")) {
|
||||||
|
editText += text.leftJustified(m_width-9) + suffix;
|
||||||
|
ui->updateStatus->setPlainText(editText);
|
||||||
|
} else {
|
||||||
|
editText += QString("\n").leftJustified(m_width-3, '=');
|
||||||
|
editText += QString("\n").leftJustified(m_width-12) + " [SUCCESS]";
|
||||||
|
}
|
||||||
|
ui->updateStatus->setText(editText);
|
||||||
|
ui->updateStatus->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onShowErrorMessage(QString title, QString text) {
|
||||||
|
QMessageBox::critical(this, title, text, QMessageBox::Ok);
|
||||||
|
}
|
37
mainwindow.h
Normal file
37
mainwindow.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui { class MainWindow; }
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "worker.h"
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWindow(Worker *worker, QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onAppendText(QString, QString);
|
||||||
|
void onShowErrorMessage(QString, QString);
|
||||||
|
void onSetProgress(quint8);
|
||||||
|
void onStopStartTimer();
|
||||||
|
void onRestartExitTimer();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onQuit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
Worker *m_worker;
|
||||||
|
int m_width;
|
||||||
|
QTimer *m_startTimer;
|
||||||
|
QTimer *m_exitTimer;
|
||||||
|
};
|
||||||
|
#endif // MAINWINDOW_H
|
78
mainwindow.ui
Normal file
78
mainwindow.ui
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>370</width>
|
||||||
|
<height>358</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Source Code Pro</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<widget class="QWidget" name="">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>11</y>
|
||||||
|
<width>351</width>
|
||||||
|
<height>341</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QTextEdit" name="updateStatus">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Noto Sans</family>
|
||||||
|
<pointsize>8</pointsize>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QProgressBar" name="updateProgress">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="start">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Terminus</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QPushButton" name="exit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -6,7 +6,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QMessageLogContext>
|
#include <QMessageLogContext>
|
||||||
|
|
||||||
#define OUTPUT_LEN (1024)
|
#define OUTPUT_LEN (1024*8)
|
||||||
|
|
||||||
static bool installedMsgHandler = false;
|
static bool installedMsgHandler = false;
|
||||||
static QtMsgType debugLevel = QtInfoMsg;
|
static QtMsgType debugLevel = QtInfoMsg;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
|
|
||||||
#define THIS_IS_CA_MASTER
|
|
||||||
|
|
||||||
struct T_emp
|
struct T_emp
|
||||||
{
|
{
|
||||||
@ -131,17 +131,17 @@ struct T_vaultRecord
|
|||||||
//16
|
//16
|
||||||
char label3buffer[4]; // mw >
|
char label3buffer[4]; // mw >
|
||||||
|
|
||||||
// Verkauf, Tür zu:
|
// Verkauf, Tuer zu:
|
||||||
uint32_t VKcoinsInserted[16]; // nur für Wechsler, soviel wurde eingeworfen
|
uint32_t VKcoinsInserted[16]; // nur fuer Wechsler, soviel wurde eingeworfen
|
||||||
uint32_t VKcoinsReturned[6]; // nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
|
uint32_t VKcoinsReturned[6]; // nur fuer Wechsler, Anzahl Muenzen pro Typ, soviel wurde zurueckgegeben
|
||||||
//88
|
//88
|
||||||
|
|
||||||
// Service, Tür offen:
|
// Service, Tuer offen:
|
||||||
uint16_t ServCoinsInserted[16]; // nur für Wechsler, soviel wurde eingeworfen
|
uint16_t ServCoinsInserted[16]; // nur fuer Wechsler, soviel wurde eingeworfen
|
||||||
uint16_t ServCoinsReturned[6]; // nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
|
uint16_t ServCoinsReturned[6]; // nur fuer Wechsler, Anzahl Muenzen pro Typ, soviel wurde zurueckgegeben
|
||||||
uint16_t resint3;
|
uint16_t resint3;
|
||||||
uint16_t resint4;
|
uint16_t resint4;
|
||||||
uint16_t currentTubeContent[6]; // nur für Wechsler, aktueller Füllstand
|
uint16_t currentTubeContent[6]; // nur fuer Wechsler, aktueller Fuellstand
|
||||||
uint16_t resint5;
|
uint16_t resint5;
|
||||||
uint16_t resint6;
|
uint16_t resint6;
|
||||||
// 56
|
// 56
|
||||||
@ -201,7 +201,7 @@ struct T_moduleCondition
|
|||||||
uint8_t temper;
|
uint8_t temper;
|
||||||
|
|
||||||
uint8_t poweronTest;
|
uint8_t poweronTest;
|
||||||
uint8_t doorState; // 1: alles zu 200: t?r offen + bit1(S) +bit2(CB) + bit3(CB)
|
uint8_t doorState; // 1: alles zu 200: tuer offen + bit1(S) +bit2(CB) + bit3(CB)
|
||||||
uint8_t doorWasOpened; // 1: all doors are closed 200: any door was just opened
|
uint8_t doorWasOpened; // 1: all doors are closed 200: any door was just opened
|
||||||
uint8_t changer; // can only be tested by usage
|
uint8_t changer; // can only be tested by usage
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ struct T_devices
|
|||||||
// set by master, used(1) or notused (0) or type 2....20
|
// set by master, used(1) or notused (0) or type 2....20
|
||||||
|
|
||||||
UCHAR kindOfPrinter; // 0:off 1:Gebe
|
UCHAR kindOfPrinter; // 0:off 1:Gebe
|
||||||
UCHAR kindOfCoinChecker; // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW)
|
UCHAR kindOfCoinChecker; // 0: without 1=EMP820 2=EMP900 3=currenza Csquare (MW)
|
||||||
UCHAR kindOfMifareReader; // by now only stronglink SL025 =1
|
UCHAR kindOfMifareReader; // by now only stronglink SL025 =1
|
||||||
UCHAR suppressSleepMode; // 0:sleep allowed 1: no sleep
|
UCHAR suppressSleepMode; // 0:sleep allowed 1: no sleep
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ public:
|
|||||||
// Furthermore the Cashagent-Library answers with status strings about sending and reading result
|
// Furthermore the Cashagent-Library answers with status strings about sending and reading result
|
||||||
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
||||||
|
|
||||||
#ifdef THIS_IS_CA_MASTER
|
|
||||||
virtual bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const =0;
|
virtual bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const =0;
|
||||||
// Command: open serial interface
|
// Command: open serial interface
|
||||||
// BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200
|
// BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200
|
||||||
@ -368,7 +368,7 @@ public:
|
|||||||
virtual void dc_closeSerial(void) const =0;
|
virtual void dc_closeSerial(void) const =0;
|
||||||
// Command: close serial interface in order to save power while power down
|
// Command: close serial interface in order to save power while power down
|
||||||
// or if another port must be used
|
// or if another port must be used
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual bool dc_isPortOpen(void) const =0;
|
virtual bool dc_isPortOpen(void) const =0;
|
||||||
// returns true if port open (don't send unless open. Sending to closed port will crash program)
|
// returns true if port open (don't send unless open. Sending to closed port will crash program)
|
||||||
@ -394,7 +394,7 @@ public:
|
|||||||
// get data back in "payLoad", max 64 byte, can be used for diagnosis
|
// get data back in "payLoad", max 64 byte, can be used for diagnosis
|
||||||
// retval = nr of bytes received. If host buffer too small then
|
// retval = nr of bytes received. If host buffer too small then
|
||||||
// only plBufSiz bytes are copied to "payLoad"
|
// only plBufSiz bytes are copied to "payLoad"
|
||||||
// plBufSizz=size of host buffer
|
// plBufSiz = size of host buffer
|
||||||
|
|
||||||
virtual void dc_setWakeFrequency(uint8_t period) const =0;
|
virtual void dc_setWakeFrequency(uint8_t period) const =0;
|
||||||
// RTC wakes DC2 (and PTU) by hardware signal every 32seconds
|
// RTC wakes DC2 (and PTU) by hardware signal every 32seconds
|
||||||
@ -403,7 +403,7 @@ public:
|
|||||||
virtual void dc_OrderToReset(void) const =0;
|
virtual void dc_OrderToReset(void) const =0;
|
||||||
// want DC2 to reset (in order to start Bootloader)
|
// want DC2 to reset (in order to start Bootloader)
|
||||||
|
|
||||||
#ifdef THIS_IS_CA_MASTER
|
|
||||||
virtual QString dc_getSerialState(void) const =0;
|
virtual QString dc_getSerialState(void) const =0;
|
||||||
// get result of opening-command like "ttyS0 opened with 115200 8N1!
|
// get result of opening-command like "ttyS0 opened with 115200 8N1!
|
||||||
// or error messages like "comport not available..."
|
// or error messages like "comport not available..."
|
||||||
@ -411,7 +411,7 @@ public:
|
|||||||
|
|
||||||
virtual void dc_clrSerialStateText(void) const =0;
|
virtual void dc_clrSerialStateText(void) const =0;
|
||||||
// clear above text to avoid multiple repetive displaying
|
// clear above text to avoid multiple repetive displaying
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const =0;
|
virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const =0;
|
||||||
// send without protocol frame, needed for the DC bootloader
|
// send without protocol frame, needed for the DC bootloader
|
||||||
@ -496,10 +496,10 @@ public:
|
|||||||
|
|
||||||
// Analog values:
|
// Analog values:
|
||||||
virtual uint32_t dc_getTemperature(void) const =0;
|
virtual uint32_t dc_getTemperature(void) const =0;
|
||||||
// in Sax-Format 0...400 (0=-50,0°C 100=0,0°C 141=20,5°C 400=150,0°C)
|
// in Sax-Format 0...400 (0=-50,0degC 100=0,0degC 141=20,5degC 400=150,0degC)
|
||||||
|
|
||||||
virtual QString dc_getTemperaturStr(void) const =0;
|
virtual QString dc_getTemperaturStr(void) const =0;
|
||||||
// as string like "-12,5°C"
|
// as string like "-12,5degC"
|
||||||
|
|
||||||
virtual uint32_t dc_getVoltage(void) const =0;
|
virtual uint32_t dc_getVoltage(void) const =0;
|
||||||
// as value in mV, 0...65,535V
|
// as value in mV, 0...65,535V
|
||||||
@ -760,7 +760,7 @@ public:
|
|||||||
uint8_t kindOfModem, uint8_t kindOfCredit ) const =0;
|
uint8_t kindOfModem, uint8_t kindOfCredit ) const =0;
|
||||||
// enable hardware in device controller:
|
// enable hardware in device controller:
|
||||||
// kindOfPrinter: 0:off 1: GPT4672 (only this one implemented)
|
// kindOfPrinter: 0:off 1: GPT4672 (only this one implemented)
|
||||||
// kindOfCoinChecker: 0:off 1:EMP820 2:EMP900 3: C²_changer
|
// kindOfCoinChecker: 0:off 1:EMP820 2:EMP900 3: Csquare_changer
|
||||||
// kindOfMifareReader: 0:off 1: SL025 (only this one implemented)
|
// kindOfMifareReader: 0:off 1: SL025 (only this one implemented)
|
||||||
// suppressSleep: 0:sleep allowed 1: sleep surpressed for special reason
|
// suppressSleep: 0:sleep allowed 1: sleep surpressed for special reason
|
||||||
// kindOfModem: 0:off 1: ATB_Sunlink_LTE (not yet implemented)
|
// kindOfModem: 0:off 1: ATB_Sunlink_LTE (not yet implemented)
|
||||||
@ -886,7 +886,7 @@ public:
|
|||||||
// send 5 byte: byte 0,1: speed 5...250 mm/s
|
// send 5 byte: byte 0,1: speed 5...250 mm/s
|
||||||
// byte2: density 0....(25)....50
|
// byte2: density 0....(25)....50
|
||||||
// byte3: alignment 'l', 'c', 'r' = left, center, right
|
// byte3: alignment 'l', 'c', 'r' = left, center, right
|
||||||
// byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!)
|
// byte4: orientation 0, 90, 180 = 0deg, 90deg, 180deg rotation (by now not supported!)
|
||||||
// not batched! don't use twice within 100ms
|
// not batched! don't use twice within 100ms
|
||||||
|
|
||||||
virtual void prn_movePaper(uint8_t wayInMm, uint8_t direction) const =0;
|
virtual void prn_movePaper(uint8_t wayInMm, uint8_t direction) const =0;
|
||||||
@ -1018,7 +1018,7 @@ public:
|
|||||||
// use for changer
|
// use for changer
|
||||||
|
|
||||||
|
|
||||||
#ifdef THIS_IS_CA_MASTER
|
|
||||||
virtual QString dc_getTxt4RsDiagWin(void) const =0;
|
virtual QString dc_getTxt4RsDiagWin(void) const =0;
|
||||||
virtual void dc_clrTxt4RsDiagWin(void) const =0;
|
virtual void dc_clrTxt4RsDiagWin(void) const =0;
|
||||||
virtual QString dc_get2ndTxt4RsDiagWin(void) const =0;
|
virtual QString dc_get2ndTxt4RsDiagWin(void) const =0;
|
||||||
@ -1033,7 +1033,6 @@ public:
|
|||||||
virtual void dc_clrTxt4dataStateLine(void) const =0;
|
virtual void dc_clrTxt4dataStateLine(void) const =0;
|
||||||
virtual QString dc_getdatifLine(void) const =0;
|
virtual QString dc_getdatifLine(void) const =0;
|
||||||
virtual void dc_clrTxt4datifLine(void) const =0;
|
virtual void dc_clrTxt4datifLine(void) const =0;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1178,7 +1177,7 @@ public:
|
|||||||
virtual uint16_t getLastInsertedCoin(void) const =0;
|
virtual uint16_t getLastInsertedCoin(void) const =0;
|
||||||
|
|
||||||
virtual bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const =0;
|
virtual bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const =0;
|
||||||
// alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64
|
// alle bei diesem Verkauf eingeworfenen Muenzen sind gespeichert, max 64
|
||||||
|
|
||||||
|
|
||||||
virtual bool cash_cancelPayment(void) const =0;
|
virtual bool cash_cancelPayment(void) const =0;
|
||||||
@ -1232,6 +1231,8 @@ public:
|
|||||||
|
|
||||||
virtual uint8_t prn_getPrintResult() const =0;
|
virtual uint8_t prn_getPrintResult() const =0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual uint8_t prn_getCurrentPrinterState() const =0;
|
virtual uint8_t prn_getCurrentPrinterState() const =0;
|
||||||
// 0: printer OK
|
// 0: printer OK
|
||||||
// bit0: near paper end bit1: no paper
|
// bit0: near paper end bit1: no paper
|
||||||
@ -1244,6 +1245,8 @@ public:
|
|||||||
virtual void sys_sendDeviceParameter(struct T_devices *deviceSettings) const =0;
|
virtual void sys_sendDeviceParameter(struct T_devices *deviceSettings) const =0;
|
||||||
|
|
||||||
virtual void sys_restoreDeviceParameter(struct T_devices *deviceSettings) const =0;
|
virtual void sys_restoreDeviceParameter(struct T_devices *deviceSettings) const =0;
|
||||||
|
// attention: only applies if function "sys_sendDeviceParameter()" was used to send this settings before
|
||||||
|
// cannot be used to see settings programmed by JsonFile
|
||||||
|
|
||||||
virtual bool sys_areDCdataValid(void) const =0;
|
virtual bool sys_areDCdataValid(void) const =0;
|
||||||
|
|
||||||
@ -1268,6 +1271,33 @@ public:
|
|||||||
|
|
||||||
virtual bool dc_isAutoRequestOn(void) const =0;
|
virtual bool dc_isAutoRequestOn(void) const =0;
|
||||||
|
|
||||||
|
virtual uint16_t log_getLatestAccountNumber(void) const=0;
|
||||||
|
// new function 27.6.2023
|
||||||
|
// latest = highest
|
||||||
|
|
||||||
|
virtual uint8_t log_getAvailableVaultBlocks(void) const=0;
|
||||||
|
// return 0x0011 1111 if all 6 blocks are loaded (one bit per block)
|
||||||
|
|
||||||
|
virtual uint8_t log_getAnswerToLastSlaveRequest(void) const =0;
|
||||||
|
// use only for ONE request/command
|
||||||
|
// return: 0xFF: result unknown by now as sending is ongoing
|
||||||
|
// 0=OK
|
||||||
|
// 1= wrong length 2=wrong start sign 5= wrong crc
|
||||||
|
// 6= slave: master cmd was wrong 7: slave: could not write/read data
|
||||||
|
// 8=timeout, got no response from slave
|
||||||
|
|
||||||
|
|
||||||
|
// use for important and extended commands (print several templates, print ticket...)
|
||||||
|
virtual void log_startSupervision(void) const =0;
|
||||||
|
|
||||||
|
virtual uint8_t log_getAnswerToLastCmdBatch(void) const =0;
|
||||||
|
// 0xFF: no command sent by now
|
||||||
|
// 0: started, in progress
|
||||||
|
// 1: done and OK
|
||||||
|
// 2: done and error
|
||||||
|
|
||||||
|
virtual bool log_getVaultData(uint8_t *data) const =0;
|
||||||
|
// get vault record in linear 8bit buffer with 320 byte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
44
update.cpp
44
update.cpp
@ -1,4 +1,5 @@
|
|||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
#include "worker.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@ -25,9 +26,9 @@
|
|||||||
#define UPDATE_OPKG (1)
|
#define UPDATE_OPKG (1)
|
||||||
#define UPDATE_DC (1)
|
#define UPDATE_DC (1)
|
||||||
#define UPDATE_PRINTER_TEMPLATES (1)
|
#define UPDATE_PRINTER_TEMPLATES (1)
|
||||||
#define UPDATE_CASH_TEMPLATE (0)
|
#define UPDATE_CASH_TEMPLATE (1)
|
||||||
#define UPDATE_CONF_TEMPLATE (0)
|
#define UPDATE_CONF_TEMPLATE (1)
|
||||||
#define UPDATE_DEVICE_TEMPLATE (0)
|
#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},
|
||||||
@ -75,6 +76,7 @@ hwinf *Update::loadDCPlugin(QDir const &plugInDir, QString const &fname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Update::Update(hwinf *hw,
|
Update::Update(hwinf *hw,
|
||||||
|
Worker *worker,
|
||||||
QString customerRepository,
|
QString customerRepository,
|
||||||
QString customerNrStr,
|
QString customerNrStr,
|
||||||
QString branchName,
|
QString branchName,
|
||||||
@ -85,6 +87,7 @@ Update::Update(hwinf *hw,
|
|||||||
char const *baudrate)
|
char const *baudrate)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_hw(hw)
|
, m_hw(hw)
|
||||||
|
, m_worker(worker)
|
||||||
, m_serialInterface(serialInterface)
|
, m_serialInterface(serialInterface)
|
||||||
, m_baudrate(baudrate)
|
, m_baudrate(baudrate)
|
||||||
, m_customerRepository(customerRepository)
|
, m_customerRepository(customerRepository)
|
||||||
@ -510,7 +513,7 @@ 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(QStringList const &filesToWorkOn) {
|
bool Update::doUpdate(int &displayIndex, QStringList const &filesToWorkOn) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// ACHTUNG !!!
|
// ACHTUNG !!!
|
||||||
@ -542,7 +545,6 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
|
|||||||
bool res = false;
|
bool res = false;
|
||||||
QString fToWorkOn = (*it).trimmed();
|
QString fToWorkOn = (*it).trimmed();
|
||||||
|
|
||||||
|
|
||||||
if (fToWorkOn.contains("dc2c", Qt::CaseInsensitive) &&
|
if (fToWorkOn.contains("dc2c", Qt::CaseInsensitive) &&
|
||||||
fToWorkOn.endsWith(".bin", Qt::CaseInsensitive)) {
|
fToWorkOn.endsWith(".bin", Qt::CaseInsensitive)) {
|
||||||
|
|
||||||
@ -582,6 +584,10 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
|
|||||||
|
|
||||||
if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
|
if ((res = updateBinary(fToWorkOn.toStdString().c_str())) == true) {
|
||||||
qCritical() << "downloaded binary" << fToWorkOn;
|
qCritical() << "downloaded binary" << fToWorkOn;
|
||||||
|
++displayIndex;
|
||||||
|
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
|
||||||
|
Worker::UPDATE_STEP_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
m_hw->dc_autoRequest(true); // turn auto-request setting on
|
||||||
@ -607,6 +613,10 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
|
|||||||
} else {
|
} else {
|
||||||
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
|
if ((res = updatePrinterTemplate(templateIdx, fToWorkOn))) {
|
||||||
qInfo() << "downloaded printer template"<< fToWorkOn;
|
qInfo() << "downloaded printer template"<< fToWorkOn;
|
||||||
|
++displayIndex;
|
||||||
|
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
|
||||||
|
Worker::UPDATE_STEP_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -614,24 +624,36 @@ bool Update::doUpdate(QStringList const &filesToWorkOn) {
|
|||||||
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
&& fToWorkOn.endsWith(".json", Qt::CaseInsensitive)) {
|
||||||
res = true;
|
res = true;
|
||||||
#if UPDATE_CASH_TEMPLATE == 1
|
#if UPDATE_CASH_TEMPLATE == 1
|
||||||
if ((res = updateCashConf(name))) {
|
if ((res = updateCashConf(fToWorkOn))) {
|
||||||
qInfo() << "downloaded cash template"<< name;
|
qInfo() << "downloaded cash template"<< fToWorkOn;
|
||||||
|
++displayIndex;
|
||||||
|
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
|
||||||
|
Worker::UPDATE_STEP_DONE);
|
||||||
}
|
}
|
||||||
#endif
|
#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 UPDATE_CONF_TEMPLATE == 1
|
||||||
if ((res= updateConfig(name))) {
|
if ((res= updateConfig(fToWorkOn))) {
|
||||||
qInfo() << "downloaded config template"<< name;
|
qInfo() << "downloaded config template"<< fToWorkOn;
|
||||||
|
++displayIndex;
|
||||||
|
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
|
||||||
|
Worker::UPDATE_STEP_DONE);
|
||||||
}
|
}
|
||||||
#endif
|
#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 UPDATE_DEVICE_TEMPLATE == 1
|
||||||
if ((res = updateDeviceConf(name))) {
|
if ((res = updateDeviceConf(fToWorkOn))) {
|
||||||
qInfo() << "downloaded device template"<< name;
|
qInfo() << "downloaded device template"<< fToWorkOn;
|
||||||
|
++displayIndex;
|
||||||
|
emit m_worker->appendText(QString("\n(") + QString("%1").arg(displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update ") + QFileInfo(fToWorkOn).fileName(),
|
||||||
|
Worker::UPDATE_STEP_DONE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
11
update.h
11
update.h
@ -9,7 +9,6 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
#include "plugins/interfaces.h"
|
#include "plugins/interfaces.h"
|
||||||
#include "apism/apism_client.h"
|
|
||||||
|
|
||||||
#ifdef PTU5
|
#ifdef PTU5
|
||||||
#define SERIAL_PORT "ttymxc2"
|
#define SERIAL_PORT "ttymxc2"
|
||||||
@ -17,15 +16,12 @@
|
|||||||
#define SERIAL_PORT "ttyUSB0"
|
#define SERIAL_PORT "ttyUSB0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Update;
|
class Worker;
|
||||||
|
|
||||||
// TODO: check hardware compatibility
|
|
||||||
// TODO: opkg commandos
|
|
||||||
|
|
||||||
class Update : public QObject {
|
class Update : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
hwinf *m_hw;
|
hwinf *m_hw;
|
||||||
|
Worker *m_worker;
|
||||||
char const *m_serialInterface;
|
char const *m_serialInterface;
|
||||||
char const *m_baudrate;
|
char const *m_baudrate;
|
||||||
QString m_customerRepository;
|
QString m_customerRepository;
|
||||||
@ -44,6 +40,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
explicit Update(hwinf *hw,
|
explicit Update(hwinf *hw,
|
||||||
|
Worker *worker,
|
||||||
QString customerRepository,
|
QString customerRepository,
|
||||||
QString customerNrStr,
|
QString customerNrStr,
|
||||||
QString branchName,
|
QString branchName,
|
||||||
@ -53,7 +50,7 @@ public:
|
|||||||
char const *serialInterface = SERIAL_PORT,
|
char const *serialInterface = SERIAL_PORT,
|
||||||
char const *baudrate = "115200");
|
char const *baudrate = "115200");
|
||||||
virtual ~Update() override;
|
virtual ~Update() override;
|
||||||
bool doUpdate(QStringList const &linesToWorkOn);
|
bool doUpdate(int &displayIndex, QStringList const &linesToWorkOn);
|
||||||
|
|
||||||
//QString customerId() { return m_customerId; }
|
//QString customerId() { return m_customerId; }
|
||||||
//QString const customerId() const { return m_customerId; }
|
//QString const customerId() const { return m_customerId; }
|
||||||
|
212
utils.cpp
212
utils.cpp
@ -1,201 +1,35 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTemporaryFile>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
#include "interfaces.h"
|
|
||||||
#include "DCPlugin/include/hwapi.h"
|
|
||||||
|
|
||||||
//#include <unistd.h>
|
int Utils::read1stLineOfFile(QString fileName) {
|
||||||
#include <thread>
|
QFile f(fileName);
|
||||||
#include <memory>
|
if (f.exists()) {
|
||||||
#include <QSharedMemory>
|
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
#include <QScopedPointer>
|
QTextStream in(&f);
|
||||||
#include <QProcess>
|
in.setCodec("UTF-8");
|
||||||
|
while(!in.atEnd()) {
|
||||||
#define COLUMN_STATUS (0)
|
return in.readLine().toInt();
|
||||||
#define COLUMN_NAME (1)
|
|
||||||
#define COLUMN_DATE_TIME (2)
|
|
||||||
#define COLUMN_RESULT (3)
|
|
||||||
|
|
||||||
Utils::Utils(QString update_ctrl_file,
|
|
||||||
QObject *parent,
|
|
||||||
char const *serialInterface,
|
|
||||||
char const *baudrate)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_hw(new hwapi())
|
|
||||||
, m_serialInterface(serialInterface)
|
|
||||||
, m_baudrate(baudrate)
|
|
||||||
, m_update_ctrl_file(update_ctrl_file)
|
|
||||||
, m_update_ctrl_file_copy(update_ctrl_file + ".copy")
|
|
||||||
, m_in(&m_update_ctrl_file)
|
|
||||||
, m_out(&m_update_ctrl_file_copy)
|
|
||||||
, m_init(true) {
|
|
||||||
|
|
||||||
if (!m_update_ctrl_file.exists()) {
|
|
||||||
qCritical() << "Update-file" << m_update_ctrl_file.fileName()
|
|
||||||
<< "does not exist";
|
|
||||||
m_init = false;
|
|
||||||
}
|
}
|
||||||
if (!m_update_ctrl_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
qCritical() << "can not open " << m_update_ctrl_file.fileName()
|
|
||||||
<< "for reading";
|
|
||||||
m_init = false;
|
|
||||||
}
|
}
|
||||||
if (!m_update_ctrl_file_copy.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
qCritical() << "can not open " << m_update_ctrl_file_copy.fileName()
|
|
||||||
<< "for writing";
|
|
||||||
m_init = false;
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::~Utils() {
|
QString Utils::zoneName(quint8 i) {
|
||||||
|
static constexpr char const *zName[] = {
|
||||||
}
|
"",
|
||||||
|
"purple",
|
||||||
void Utils::updateBinary(char const *fileToSendToDC) {
|
"blue",
|
||||||
qDebug() << "file to send to DC ..." << fileToSendToDC;
|
"yellow",
|
||||||
qDebug() << "baudrate ............." << m_baudrate;
|
"green",
|
||||||
qDebug() << "serial interface ....." << m_serialInterface;
|
"yellow (mars)",
|
||||||
m_hw->dc_updateDC(fileToSendToDC, m_baudrate, m_serialInterface);
|
"green (mars)"
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
};
|
||||||
QCoreApplication::quit();
|
if (i < (sizeof(zName)/sizeof(char const *))) {
|
||||||
}
|
return zName[i];
|
||||||
|
}
|
||||||
void Utils::updatePrinterConf(int nrOfTemplate, char const *fileToSendToDC) {
|
return "N/A";
|
||||||
QVector<int> printTemplates{ nrOfTemplate };
|
|
||||||
QVector<QString> filesToSend{ fileToSendToDC };
|
|
||||||
|
|
||||||
m_hw->dc_updatePrinterTemplate(hwapi::FileTypeJson::PRINTER,
|
|
||||||
printTemplates, filesToSend,
|
|
||||||
QString(m_baudrate),
|
|
||||||
QString(m_serialInterface));
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
|
||||||
QCoreApplication::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Utils::getOpenLines() {
|
|
||||||
QStringList openLines;
|
|
||||||
|
|
||||||
while (!m_in.atEnd()) {
|
|
||||||
QString line = m_in.readLine().trimmed();
|
|
||||||
// QString.split() is defined >= 5.14
|
|
||||||
if (!line.startsWith("OPEN")) {
|
|
||||||
m_out << line;
|
|
||||||
} else {
|
|
||||||
openLines << line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return openLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::doUpdate() {
|
|
||||||
/*
|
|
||||||
The file referred to by 'update_data' has the following structure for
|
|
||||||
each line:
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# STATUS | NAME | DATE | RESULT
|
|
||||||
# ======================================================================
|
|
||||||
# where
|
|
||||||
#
|
|
||||||
# STATUS: OPEN or CLOSED
|
|
||||||
# NAME : If starting with 'opkg' it is an opkg-command to be executed.
|
|
||||||
# Otherwise its the name of a file which has to be updated.
|
|
||||||
# DATE : 0000-00-00T00:00:00
|
|
||||||
# RESULT: SUCCESS or ERROR (possibly with description)
|
|
||||||
#
|
|
||||||
*/
|
|
||||||
if (!m_init) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList openLines = getOpenLines();
|
|
||||||
|
|
||||||
bool res = false;
|
|
||||||
QList<QString>::const_iterator it;
|
|
||||||
for (it = openLines.cbegin(); it != openLines.cend(); ++it) {
|
|
||||||
int start = 0, end;
|
|
||||||
int column = 0;
|
|
||||||
QString status, name, datetime, result;
|
|
||||||
QString line = *it;
|
|
||||||
while ((end = line.indexOf(QChar(','), start)) != -1) {
|
|
||||||
QString next = line.mid(start, end).trimmed();
|
|
||||||
switch (column) {
|
|
||||||
case COLUMN_STATUS:
|
|
||||||
status = next;
|
|
||||||
break;
|
|
||||||
case COLUMN_NAME:
|
|
||||||
name = next;
|
|
||||||
break;
|
|
||||||
case COLUMN_DATE_TIME:
|
|
||||||
datetime = next;
|
|
||||||
break;
|
|
||||||
case COLUMN_RESULT:
|
|
||||||
result = next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++column;
|
|
||||||
start = end + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!status.contains("OPEN")) {
|
|
||||||
qCritical() << "Parsing error for" << m_update_ctrl_file.fileName();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (name.contains("dc2c") && name.endsWith(".bin")) {
|
|
||||||
updateBinary(name.toStdString().c_str());
|
|
||||||
res = true;
|
|
||||||
} else
|
|
||||||
if (name.contains("DC2C_print") && name.endsWith(".json")) {
|
|
||||||
int i = name.indexOf("DC2C_print");
|
|
||||||
int templateIdx = name.mid(i).midRef(10, 2).toInt();
|
|
||||||
updatePrinterConf(templateIdx, name.toStdString().c_str());
|
|
||||||
res = true;
|
|
||||||
} else
|
|
||||||
if (name.contains("opkg")) {
|
|
||||||
int i = name.indexOf("opkg ");
|
|
||||||
QString rest = name.mid(i).trimmed();
|
|
||||||
QScopedPointer<QProcess> p(new QProcess(this));
|
|
||||||
p->setProcessChannelMode(QProcess::MergedChannels);
|
|
||||||
p->start("opkg", QStringList() << rest);
|
|
||||||
if (p->waitForStarted(1000)) {
|
|
||||||
if (p->state() == QProcess::ProcessState::Running) {
|
|
||||||
if (p->waitForFinished(10000)) {
|
|
||||||
QByteArray output = p->readAllStandardOutput();
|
|
||||||
qCritical() << output;
|
|
||||||
res = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
QString resultLine = "CLOSED";
|
|
||||||
resultLine += ", " + name;
|
|
||||||
resultLine += ", " + QDateTime::currentDateTime().toString(Qt::ISODate);
|
|
||||||
resultLine += ", " + (res == true) ? "SUCCESS" : "ERROR";
|
|
||||||
m_out << resultLine;
|
|
||||||
} // for (it = openLines.cbegin(); it != openLines.end(); ++it) {
|
|
||||||
|
|
||||||
return finishUpdate(openLines.size() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::finishUpdate(bool replaceCtrlFile) {
|
|
||||||
if (replaceCtrlFile) {
|
|
||||||
if (!m_update_ctrl_file_copy.exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!m_update_ctrl_file.remove()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!m_update_ctrl_file_copy.rename(m_update_ctrl_file.fileName())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
41
utils.h
41
utils.h
@ -5,42 +5,9 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include <memory>
|
namespace Utils {
|
||||||
|
int read1stLineOfFile(QString fileName);
|
||||||
|
QString zoneName(quint8 i);
|
||||||
|
}
|
||||||
|
|
||||||
#include "interfaces.h"
|
|
||||||
#include "DCPlugin/include/hwapi.h"
|
|
||||||
|
|
||||||
#ifdef PTU5
|
|
||||||
#define SERIAL_PORT "ttymxc2"
|
|
||||||
#else
|
|
||||||
#define SERIAL_PORT "ttyUSB0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Utils : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
std::unique_ptr<hwinf> m_hw;
|
|
||||||
char const *m_serialInterface;
|
|
||||||
char const *m_baudrate;
|
|
||||||
QFile m_update_ctrl_file;
|
|
||||||
QFile m_update_ctrl_file_copy;
|
|
||||||
QTextStream m_in;
|
|
||||||
QTextStream m_out;
|
|
||||||
|
|
||||||
bool m_init;
|
|
||||||
|
|
||||||
void updateBinary(char const *fileToSendToDC);
|
|
||||||
void updatePrinterConf(int nrOfTemplate, char const *fileToSendToDC);
|
|
||||||
bool finishUpdate(bool finish);
|
|
||||||
QStringList getOpenLines();
|
|
||||||
static constexpr QChar SEPARATOR = QChar(',');
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Utils(QString update_ctrl_file,
|
|
||||||
QObject *parent = nullptr,
|
|
||||||
char const *serialInterface = SERIAL_PORT,
|
|
||||||
char const *baudrate = "115200");
|
|
||||||
virtual ~Utils() override;
|
|
||||||
bool doUpdate();
|
|
||||||
};
|
|
||||||
#endif // UTILS_H_INCLUDED
|
#endif // UTILS_H_INCLUDED
|
||||||
|
857
worker.cpp
857
worker.cpp
@ -12,25 +12,20 @@
|
|||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QJsonParseError>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "plugins/interfaces.h"
|
#include "plugins/interfaces.h"
|
||||||
#include "ismas/ismas_client.h"
|
#include "ismas/ismas_client.h"
|
||||||
#include "apism/apism_client.h"
|
|
||||||
|
|
||||||
int Worker::read1stLineOfFile(QString fileName) {
|
QString const Worker::UPDATE_STEP_OK(" [ ok]");
|
||||||
QFile f(fileName);
|
QString const Worker::UPDATE_STEP_DONE(" [done]");
|
||||||
if (f.exists()) {
|
QString const Worker::UPDATE_STEP_FAIL(" [fail]");
|
||||||
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
QString const Worker::UPDATE_STEP_SUCCESS(" [SUCCESS]");
|
||||||
QTextStream in(&f);
|
|
||||||
in.setCodec("UTF-8");
|
|
||||||
while(!in.atEnd()) {
|
|
||||||
return in.readLine().toInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Worker::Worker(hwinf *hw,
|
Worker::Worker(hwinf *hw,
|
||||||
int customerNr,
|
int customerNr,
|
||||||
@ -38,14 +33,12 @@ Worker::Worker(hwinf *hw,
|
|||||||
int zoneNr,
|
int zoneNr,
|
||||||
QString branchName,
|
QString branchName,
|
||||||
QString workingDirectory,
|
QString workingDirectory,
|
||||||
bool maintenanceMode,
|
|
||||||
bool dryRun,
|
bool dryRun,
|
||||||
QObject *parent,
|
QObject *parent,
|
||||||
char const *serialInterface,
|
char const *serialInterface,
|
||||||
char const *baudrate)
|
char const *baudrate)
|
||||||
: m_hw(hw)
|
: m_hw(hw)
|
||||||
, m_workerThread("workerThread")
|
, m_workerThread("workerThread")
|
||||||
, m_apismClient(0, 0, 0, this) // TODO
|
|
||||||
, m_customerNr(customerNr)
|
, m_customerNr(customerNr)
|
||||||
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
|
, m_customerNrStr(QString("customer_") + QString::number(m_customerNr).rightJustified(3, '0'))
|
||||||
, m_machineNr(machineNr)
|
, m_machineNr(machineNr)
|
||||||
@ -54,8 +47,9 @@ Worker::Worker(hwinf *hw,
|
|||||||
, m_branchName(branchName)
|
, m_branchName(branchName)
|
||||||
, m_customerRepositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr))
|
, m_customerRepositoryPath(QString("https://git.mimbach49.de/GerhardHoffmann/%1.git").arg(m_customerNrStr))
|
||||||
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
|
, m_customerRepository(QDir::cleanPath(m_workingDirectory + QDir::separator() + m_customerNrStr))
|
||||||
|
, m_update(new Update(m_hw, this, m_customerRepository, m_customerNrStr, m_branchName,
|
||||||
|
m_workingDirectory, dryRun, parent, serialInterface, baudrate))
|
||||||
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
|
, m_gc(m_customerNrStr, m_customerRepository, m_workingDirectory, m_branchName, this)
|
||||||
, m_maintenanceMode(maintenanceMode)
|
|
||||||
, m_osVersion(getOsVersion())
|
, m_osVersion(getOsVersion())
|
||||||
, m_atbqtVersion(getATBQTVersion())
|
, m_atbqtVersion(getATBQTVersion())
|
||||||
, m_cpuSerial(getCPUSerial())
|
, m_cpuSerial(getCPUSerial())
|
||||||
@ -69,7 +63,9 @@ Worker::Worker(hwinf *hw,
|
|||||||
, m_pluginVersionPrmCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin_ConfigUi.so"))
|
, m_pluginVersionPrmCalcConfig(getPluginVersion("/opt/app/ATBAPP/plugins/libPRM_CalculatePricePlugin_ConfigUi.so"))
|
||||||
, m_pluginVersionTcpZvt(getPluginVersion("/opt/app/ATBAPP/plugins/libTCP_ZVT_CCPlugin.so"))
|
, m_pluginVersionTcpZvt(getPluginVersion("/opt/app/ATBAPP/plugins/libTCP_ZVT_CCPlugin.so"))
|
||||||
, m_ismasUpdateRequests(ISMAS_UPDATE_REQUESTS)
|
, m_ismasUpdateRequests(ISMAS_UPDATE_REQUESTS)
|
||||||
, m_waitForNewUpdates(this) {
|
, m_waitForNewUpdates(this)
|
||||||
|
, m_filesToUpdate()
|
||||||
|
, m_updateProcessRunning(false) {
|
||||||
|
|
||||||
QDir::setCurrent(m_workingDirectory);
|
QDir::setCurrent(m_workingDirectory);
|
||||||
|
|
||||||
@ -86,13 +82,6 @@ Worker::Worker(hwinf *hw,
|
|||||||
qInfo() << "BRANCH_NAME ................" << m_branchName;
|
qInfo() << "BRANCH_NAME ................" << m_branchName;
|
||||||
qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory;
|
qInfo() << "WORKING_DIRECTORY .........." << m_workingDirectory;
|
||||||
|
|
||||||
//QProcess p;
|
|
||||||
//p.start("/bin/systemctl", {"restart", "apism"});
|
|
||||||
//if (!p.waitForStarted(5000) || !p.waitForFinished(5000)) {
|
|
||||||
// qCritical() << "APISM-RESTART-FAILURE";
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
this->moveToThread(&m_workerThread);
|
this->moveToThread(&m_workerThread);
|
||||||
m_workerThread.start();
|
m_workerThread.start();
|
||||||
|
|
||||||
@ -104,47 +93,6 @@ Worker::Worker(hwinf *hw,
|
|||||||
}
|
}
|
||||||
QThread::sleep(1);
|
QThread::sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(&m_apismClient, SIGNAL(ismasResponseAvailable(QJsonObject)), this,
|
|
||||||
SLOT(onIsmasResponseReceived(QJsonObject)));
|
|
||||||
connect(this, SIGNAL(summarizeRepositoryStatus()), this,
|
|
||||||
SLOT(onSummarizeRepositoryStatus()), Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(sendCmdSendVersionToIsmas()), this,
|
|
||||||
SLOT(onSendCmdSendVersionToIsmas()), Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(summarizeUpload(QStringList)), this,
|
|
||||||
SLOT(onSummarizeUpload(QStringList)), Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(handleChangedFiles(QStringList)), this,
|
|
||||||
SLOT(onHandleChangedFiles(QStringList)), Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(finishUpdateProcess(bool)), this,
|
|
||||||
SLOT(onFinishUpdateProcess(bool)), Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(terminateUpdateProcess()), this,
|
|
||||||
SLOT(onTerminateUpdateProcess()), Qt::QueuedConnection);
|
|
||||||
|
|
||||||
connect(&m_emergencyTimer, SIGNAL(timeout()), this, SLOT(onTerminateUpdateProcess()), Qt::QueuedConnection);
|
|
||||||
m_emergencyTimer.setSingleShot(true);
|
|
||||||
m_emergencyTimer.start(1000 * 60 * 10);
|
|
||||||
|
|
||||||
QDir customerRepository(m_customerRepository);
|
|
||||||
if (!customerRepository.exists()) {
|
|
||||||
if (m_gc.gitCloneAndCheckoutBranch()) {
|
|
||||||
// do nothing else, not even executing opkg-commands
|
|
||||||
emit this->finishUpdateProcess(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_update = new Update(m_hw,
|
|
||||||
m_customerRepository,
|
|
||||||
m_customerNrStr,
|
|
||||||
m_branchName,
|
|
||||||
m_workingDirectory,
|
|
||||||
dryRun, parent, serialInterface, baudrate);
|
|
||||||
|
|
||||||
connect(&m_startUpdateProcess, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
|
||||||
m_startUpdateProcess.setSingleShot(true);
|
|
||||||
m_startUpdateProcess.start(1000);
|
|
||||||
|
|
||||||
connect(&m_waitForNewUpdates, SIGNAL(timeout()), this, SLOT(askIsmasForNewData()), Qt::QueuedConnection);
|
|
||||||
m_waitForNewUpdates.setSingleShot(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker::~Worker() {
|
Worker::~Worker() {
|
||||||
@ -163,6 +111,428 @@ Worker::~Worker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::once_flag once;
|
||||||
|
void Worker::update() {
|
||||||
|
std::call_once(once, &Worker::privateUpdate, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Worker::privateUpdate() {
|
||||||
|
// user should not start the update process several times
|
||||||
|
QPushButton *start = qobject_cast<QPushButton *>(QObject::sender());
|
||||||
|
start->setEnabled(false);
|
||||||
|
|
||||||
|
emit stopStartTimer();
|
||||||
|
m_updateProcessRunning = true;
|
||||||
|
|
||||||
|
bool sentIsmasLastVersionNotification = false;
|
||||||
|
|
||||||
|
QDir customerRepository(m_customerRepository);
|
||||||
|
if (!customerRepository.exists()) {
|
||||||
|
if (m_gc.gitCloneAndCheckoutBranch()) {
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_PROCESS_SUCCESS,
|
||||||
|
QString("CLONED AND CHECKED OUT: ") + m_customerRepository);
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.cloneAndCheckoutCustomerRepository(
|
||||||
|
m_updateStatus.m_statusDescription));
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.updateOfPSASucceeded(""));
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// checkout branch
|
||||||
|
if (m_gc.gitCheckoutBranch()) {
|
||||||
|
int progress = 10;
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH,
|
||||||
|
QString("CHECKED OUT BRANCH: ") + m_gc.branchName());
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.checkoutBranch(
|
||||||
|
m_updateStatus.m_statusDescription, ""));
|
||||||
|
|
||||||
|
emit setProgress(progress);
|
||||||
|
if (backendConnected()) {
|
||||||
|
progress = 20;
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (updateTriggerSet()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (customerEnvironment()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (filesToUpdate()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (updateFiles(progress)) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (syncCustomerRepositoryAndFS()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
if (sendIsmasLastVersionNotification()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
sentIsmasLastVersionNotification = true;
|
||||||
|
if (saveLogFile()) {
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
emit appendText(QString(""), UPDATE_STEP_SUCCESS);
|
||||||
|
|
||||||
|
// mark update as activated -> this resets the WAIT button
|
||||||
|
progress = 100;
|
||||||
|
emit setProgress(progress);
|
||||||
|
m_ismasClient.setProgressInPercent(progress);
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.updateOfPSAActivated());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sentIsmasLastVersionNotification) {
|
||||||
|
// try even if the backend is not connected
|
||||||
|
sendIsmasLastVersionNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_updateProcessRunning = false;
|
||||||
|
emit restartExitTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::backendConnected() {
|
||||||
|
static int repeat = 0;
|
||||||
|
|
||||||
|
if (repeat < 3) {
|
||||||
|
std::optional<QString> result
|
||||||
|
= IsmasClient::sendRequestReceiveResponse(
|
||||||
|
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_SELF#J={}");
|
||||||
|
if (result) {
|
||||||
|
QString msg = result.value();
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qCritical() << "(2) INVALID JSON MSG: PARSING FAILED (msg=" << msg << "):"
|
||||||
|
<< parseError.error << parseError.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!document.isObject()) {
|
||||||
|
qCritical() << "FILE IS NOT A JSON OBJECT!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject obj = document.object();
|
||||||
|
QStringList keys = obj.keys();
|
||||||
|
for (QString const& key : keys ) {
|
||||||
|
if (key.contains("CMD_GET_APISMSTATUS_RESPONSE")) {
|
||||||
|
QJsonValue v = obj.value(key);
|
||||||
|
if (v.isObject()) {
|
||||||
|
obj = v.toObject();
|
||||||
|
bool ismas = obj.value("ISMAS").toBool();
|
||||||
|
QString status = obj.value("Broker").toString();
|
||||||
|
|
||||||
|
qCritical() << "XXXXXXXXXX STATUS" << status;
|
||||||
|
|
||||||
|
if (ismas) {
|
||||||
|
if (status == "Connected") {
|
||||||
|
// do not send, as this would result in a corrupted wait button
|
||||||
|
// but update the user-interface
|
||||||
|
emit appendText("\nBackend connected", UPDATE_STEP_OK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status.startsWith("Connecting") || status.startsWith("Re-Connecting")) {
|
||||||
|
QThread::sleep(1);
|
||||||
|
++repeat;
|
||||||
|
return backendConnected();
|
||||||
|
}
|
||||||
|
emit appendText("\nBackend connected", UPDATE_STEP_FAIL);
|
||||||
|
emit showErrorMessage("Error", "Backend not available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::BACKEND_NOT_CONNECTED,
|
||||||
|
QString("NO BACKEND CONNECTION"));
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.errorBackendNotConnected(m_updateStatus.m_statusDescription, ""));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::updateTriggerSet() {
|
||||||
|
// nmap -Pn 62.141.45.68 -p 8883
|
||||||
|
// Host is up (0.053s latency).
|
||||||
|
//
|
||||||
|
// PORT STATE SERVICE
|
||||||
|
// 8883/tcp open secure-mqtt
|
||||||
|
|
||||||
|
QString triggerValue("");
|
||||||
|
|
||||||
|
if (std::optional<QString> result
|
||||||
|
= IsmasClient::sendRequestReceiveResponse(
|
||||||
|
IsmasClient::APISM::DIRECT_PORT, "#M=APISM#C=REQ_ISMASPARAMETER#J={}")) {
|
||||||
|
QString msg = result.value();
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qCritical() << "(2) INVALID JSON MSG: PARSING FAILED (msg=" << msg << "):"
|
||||||
|
<< parseError.error << parseError.errorString();
|
||||||
|
emit showErrorMessage("check update trigger",
|
||||||
|
QString("invalid json ") + msg.mid(0, 20));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!document.isObject()) {
|
||||||
|
qCritical() << "FILE IS NOT A JSON OBJECT!";
|
||||||
|
emit showErrorMessage("check update trigger",
|
||||||
|
QString("not a json object") + msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject obj = document.object();
|
||||||
|
// sanity check: cust_nr and machine_nr of PSA correct ?
|
||||||
|
if (obj.contains("Dev_ID")) {
|
||||||
|
QJsonValue v = obj.value("Dev_ID");
|
||||||
|
if (v.isObject()) {
|
||||||
|
QJsonObject obj = v.toObject();
|
||||||
|
if (obj.contains("Custom_ID") && obj.contains("Device_ID")) {
|
||||||
|
QJsonValue const c = obj.value("Custom_ID");
|
||||||
|
QJsonValue const m = obj.value("Device_ID");
|
||||||
|
int customerNr = c.toInt(-1);
|
||||||
|
int machineNr = m.toInt(-1);
|
||||||
|
if (customerNr != m_customerNr) {
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
|
||||||
|
QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)")
|
||||||
|
.arg(customerNr).arg(m_customerNr));
|
||||||
|
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||||
|
m_updateStatus.m_statusDescription));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (machineNr != m_machineNr) {
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
|
||||||
|
QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)")
|
||||||
|
.arg(machineNr).arg(m_machineNr));
|
||||||
|
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
|
||||||
|
m_updateStatus.m_statusDescription));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj.contains("Fileupload")) {
|
||||||
|
QJsonValue v = obj.value("Fileupload");
|
||||||
|
if (v.isObject()) {
|
||||||
|
obj = v.toObject();
|
||||||
|
if (obj.contains("TRG")) {
|
||||||
|
v = obj.value("TRG");
|
||||||
|
if (v.isString()) {
|
||||||
|
triggerValue = v.toString();
|
||||||
|
if (triggerValue == "WAIT") {
|
||||||
|
emit appendText("\nUpdate trigger set", UPDATE_STEP_OK);
|
||||||
|
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_TRIGGER_SET,
|
||||||
|
QString("UPDATE TRIGGER SET. CONTINUE. "));
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.updateTriggerSet(m_updateStatus.m_statusDescription, ""));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("check update trigger",
|
||||||
|
QString ("TRG key=<") + triggerValue
|
||||||
|
+ ">\n(reset download button?)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("check update trigger", "TRG key not contained");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("check update trigger", "Fileupload not a json-object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("check update trigger", "no ISMAS response");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::UPDATE_TRIGGER_NOT_SET_OR_WRONG,
|
||||||
|
QString("UPDATE-TRIGGER-NOT-SET-OR-WRONG: VALUE=(") +
|
||||||
|
triggerValue + ")");
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.errorUpdateTrigger(m_updateStatus.m_statusDescription, ""));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::customerEnvironment() {
|
||||||
|
if (QDir(m_customerRepository).exists()) {
|
||||||
|
if (m_gc.gitCheckoutBranch()) {
|
||||||
|
emit appendText("\nPrepare customer environment", UPDATE_STEP_DONE);
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_CHECKOUT_BRANCH,
|
||||||
|
QString("CHECKED-OUT BRANCH ") + m_gc.branchName());
|
||||||
|
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.checkoutBranch(m_updateStatus.m_statusDescription, ""));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("cust-env",
|
||||||
|
QString("Checkout ") + m_customerRepository + " failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("cust-env", m_customerRepository + " does not exist");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::filesToUpdate() {
|
||||||
|
if (std::optional<QString> changes = m_gc.gitFetch()) {
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::GIT_FETCH_UPDATES,
|
||||||
|
QString("FETCHING OF ") + m_customerRepositoryPath +
|
||||||
|
QString(" INTO ") + m_customerRepository);
|
||||||
|
|
||||||
|
if (std::optional<QStringList> changedFileNames = m_gc.gitDiff(changes.value())) {
|
||||||
|
m_filesToUpdate = changedFileNames.value();
|
||||||
|
int const size = m_filesToUpdate.size();
|
||||||
|
if (size > 1) {
|
||||||
|
emit appendText(QString("\nFound %1 files to update ").arg(size), UPDATE_STEP_DONE);
|
||||||
|
} else {
|
||||||
|
emit appendText(QString("\nFound 1 file to update "), UPDATE_STEP_DONE);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("files to update", "no files to update (checked-in any files?)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit showErrorMessage("files to update",
|
||||||
|
QString("no changes in ") + m_customerRepository +
|
||||||
|
" (checked-in any files?)");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::updateFiles(quint8 percent) {
|
||||||
|
QStringList filesToDownload;
|
||||||
|
m_displayIndex = 0;
|
||||||
|
for (int i = 0; i < m_filesToUpdate.size(); ++i) {
|
||||||
|
QString fName = m_filesToUpdate.at(i);
|
||||||
|
if (fName.contains("opkg_commands", Qt::CaseInsensitive)) {
|
||||||
|
// execute opkg commands
|
||||||
|
if (QDir::setCurrent(m_customerRepository)) {
|
||||||
|
QFile f(fName);
|
||||||
|
if (f.exists()) {
|
||||||
|
if (f.open(QIODevice::ReadOnly)) {
|
||||||
|
QTextStream in(&f);
|
||||||
|
int cmdCount = 0;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString line = in.readLine();
|
||||||
|
static const QRegularExpression comment("^\\s*#.*$");
|
||||||
|
if (line.indexOf(comment, 0) == -1) {
|
||||||
|
// found opkg command
|
||||||
|
QString opkgCommand = line.trimmed();
|
||||||
|
executeOpkgCommand(opkgCommand);
|
||||||
|
++cmdCount;
|
||||||
|
|
||||||
|
m_ismasClient.setProgressInPercent(++percent);
|
||||||
|
m_updateStatus = UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND,
|
||||||
|
QString("EXEC OPKG-COMMAND ") + opkgCommand);
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_EVENT#J=") +
|
||||||
|
m_ismasClient.execOpkgCommand(m_updateStatus.m_statusDescription, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
if (cmdCount > 0) {
|
||||||
|
m_displayIndex = 1;
|
||||||
|
emit appendText(QString("\n(") + QString("%1").arg(m_displayIndex).rightJustified(2, ' ') + QString(")")
|
||||||
|
+ QString(" Update opkg pakets "), UPDATE_STEP_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (fName.contains("print", Qt::CaseInsensitive)) {
|
||||||
|
filesToDownload << fName; // download printer-config-files
|
||||||
|
} else
|
||||||
|
if (fName == "dc2c.bin") {
|
||||||
|
filesToDownload << fName; // download device controller
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << "XXXXXXXXXXXXXXXXXXX FILES_TO_WORK_ON" << filesToDownload;
|
||||||
|
|
||||||
|
return m_update->doUpdate(m_displayIndex, filesToDownload);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::syncCustomerRepositoryAndFS() {
|
||||||
|
if (QDir(m_customerRepository).exists()) {
|
||||||
|
if (QDir::setCurrent(m_customerRepository)) {
|
||||||
|
QString const params("--recursive "
|
||||||
|
"--progress "
|
||||||
|
"--checksum "
|
||||||
|
"--exclude=.* "
|
||||||
|
"--include=*.bin "
|
||||||
|
"--include=*.json "
|
||||||
|
"--include=opkg_commands "
|
||||||
|
"--include=*.ini");
|
||||||
|
QStringList cmds;
|
||||||
|
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
|
||||||
|
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
|
||||||
|
|
||||||
|
QString cmd;
|
||||||
|
bool error = false;
|
||||||
|
foreach (cmd, cmds) {
|
||||||
|
if (!error) {
|
||||||
|
Command c("bash");
|
||||||
|
qInfo() << "EXECUTING CMD..." << cmd;
|
||||||
|
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
|
||||||
|
qCritical() << c.getCommandResult() << "SUCCESS";
|
||||||
|
} else {
|
||||||
|
qCritical() << "CMD" << cmd << "FAILED";
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!error) {
|
||||||
|
emit appendText(QString("\nSync customer environment with filesystem "),
|
||||||
|
UPDATE_STEP_DONE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::sendIsmasLastVersionNotification() {
|
||||||
|
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
|
||||||
|
QString("#M=APISM#C=CMD_SENDVERSION#J=") +
|
||||||
|
m_ismasClient.updateOfPSASendVersion(getPSAInstalled()));
|
||||||
|
emit appendText(QString("\nSend last version info "), UPDATE_STEP_DONE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Worker::saveLogFile() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
QString Worker::getOsVersion() const {
|
QString Worker::getOsVersion() const {
|
||||||
QString const cmd = QString("echo -n $(cat /etc/os-release | head -n 1 | cut -d'\"' -f2 | tr -d '\"')");
|
QString const cmd = QString("echo -n $(cat /etc/os-release | head -n 1 | cut -d'\"' -f2 | tr -d '\"')");
|
||||||
Command c("bash");
|
Command c("bash");
|
||||||
@ -245,132 +615,7 @@ qint64 Worker::getFileSize(QString const &fileName) const {
|
|||||||
return fInfo.exists() ? fInfo.size() : -1;
|
return fInfo.exists() ? fInfo.size() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::onHandleChangedFiles(QStringList changedFiles) {
|
bool Worker::executeOpkgCommand(QString opkgCommand) {
|
||||||
|
|
||||||
QString opkg_commands;
|
|
||||||
static const QRegularExpression re("^.*opkg_commands\\s*$");
|
|
||||||
static const QRegularExpression comment("^\\s*#.*$");
|
|
||||||
int idx = changedFiles.indexOf(re);
|
|
||||||
if (idx != -1) {
|
|
||||||
opkg_commands = changedFiles.takeAt(idx);
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMANDS,
|
|
||||||
QString("EXEC OPKG-COMMANDS FOR ") + opkg_commands);
|
|
||||||
|
|
||||||
if (QDir::setCurrent(m_customerRepository)) {
|
|
||||||
QFile f(opkg_commands);
|
|
||||||
if (f.exists()) {
|
|
||||||
if (f.open(QIODevice::ReadOnly)) {
|
|
||||||
QTextStream in(&f);
|
|
||||||
while (!in.atEnd()) {
|
|
||||||
QString line = in.readLine();
|
|
||||||
if (line.indexOf(comment, 0) == -1) {
|
|
||||||
// found opkg command
|
|
||||||
QString opkgCommand = line.trimmed();
|
|
||||||
executeOpkgCommand(opkgCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMANDS_SUCCESS,
|
|
||||||
QString("EXECUTING OPKG-COMMANDS OK"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_update->doUpdate(changedFiles)) { // first update the hardware
|
|
||||||
// then sync the file-system
|
|
||||||
if (QDir(m_customerRepository).exists()) {
|
|
||||||
if (QDir::setCurrent(m_customerRepository)) {
|
|
||||||
QString const params("--recursive "
|
|
||||||
"--progress "
|
|
||||||
"--checksum "
|
|
||||||
"--exclude=.* "
|
|
||||||
"--include=*.bin "
|
|
||||||
"--include=*.json "
|
|
||||||
"--include=opkg_commands "
|
|
||||||
"--include=*.ini");
|
|
||||||
QStringList cmds;
|
|
||||||
cmds << QString("rsync ") + params.simplified() + " etc/ /etc";
|
|
||||||
cmds << QString("rsync ") + params.simplified() + " opt/ /opt";
|
|
||||||
|
|
||||||
QString cmd;
|
|
||||||
bool error = false;
|
|
||||||
foreach (cmd, cmds) {
|
|
||||||
if (!error) {
|
|
||||||
Command c("bash");
|
|
||||||
qInfo() << "EXCUTING CMD..." << cmd;
|
|
||||||
if (c.execute(m_customerRepository, QStringList() << "-c" << cmd)) {
|
|
||||||
qDebug() << c.getCommandResult();
|
|
||||||
} else {
|
|
||||||
qCritical() << "CMD" << cmd << "FAILED";
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!error) {
|
|
||||||
emit this->finishUpdateProcess(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onTerminateUpdateProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::onSummarizeUpload(QStringList changedFiles) {
|
|
||||||
QDateTime const c = QDateTime::currentDateTime();
|
|
||||||
QDate const d = c.date();
|
|
||||||
QTime const t = c.time();
|
|
||||||
|
|
||||||
QString uploadHistoryFile = QString("upload_history_%1%2%3T%4%5%6.txt")
|
|
||||||
.arg(d.year()).arg(d.month()).arg(d.day())
|
|
||||||
.arg(t.hour()).arg(t.minute()).arg(t.second());
|
|
||||||
|
|
||||||
QFile f(uploadHistoryFile);
|
|
||||||
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
QTextStream out(&f);
|
|
||||||
QString fName;
|
|
||||||
foreach (fName, changedFiles) {
|
|
||||||
QString lastCommit = m_gc.gitLastCommit(fName);
|
|
||||||
out << fName << ":" << lastCommit << "\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: error an ISMAS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::onSummarizeRepositoryStatus() {
|
|
||||||
// TODO
|
|
||||||
QString dir("/opt/app/tools/atbupdate/customer_999");
|
|
||||||
QDirIterator it(dir, QStringList() << "*.jpg",
|
|
||||||
QDir::Files, QDirIterator::Subdirectories);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
qDebug() << it.next();
|
|
||||||
if (m_gc.gitIsFileTracked(it.next())) {
|
|
||||||
QString lastCommit = m_gc.gitLastCommit(it.next());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
QString repoStatusHistoryFile = QString("repo_status_history_%1%2%3T%4%5%6.txt")
|
|
||||||
.arg(d.year()).arg(d.month()).arg(d.day())
|
|
||||||
.arg(t.hour()).arg(t.minute()).arg(t.second());
|
|
||||||
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
QTextStream out(&f);
|
|
||||||
QString fName;
|
|
||||||
foreach (fName, changedFiles) {
|
|
||||||
QString lastCommit = m_gc.gitLastCommit(fName);
|
|
||||||
out << fName << ":" << lastCommit << "\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: error an ISMAS
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::executeOpkgCommand(QString opkgCommand) {
|
|
||||||
Command c(opkgCommand);
|
Command c(opkgCommand);
|
||||||
if (c.execute(m_workingDirectory)) {
|
if (c.execute(m_workingDirectory)) {
|
||||||
QString const r = c.getCommandResult();
|
QString const r = c.getCommandResult();
|
||||||
@ -378,115 +623,92 @@ void Worker::executeOpkgCommand(QString opkgCommand) {
|
|||||||
QString("EXECUTE OPKG COMMAND %1 OK: %2")
|
QString("EXECUTE OPKG COMMAND %1 OK: %2")
|
||||||
.arg(opkgCommand)
|
.arg(opkgCommand)
|
||||||
.arg(c.getCommandResult()));
|
.arg(c.getCommandResult()));
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
qCritical() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE,
|
qCritical() << UpdateStatus(UPDATE_STATUS::EXEC_OPKG_COMMAND_FAILURE,
|
||||||
QString("EXECUTE OPKG COMMAND %1 FAILED")
|
QString("EXECUTE OPKG COMMAND %1 FAILED")
|
||||||
.arg(opkgCommand));
|
.arg(opkgCommand));
|
||||||
onTerminateUpdateProcess();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sollte ParameterResponse heissen
|
PSAInstalled Worker::getPSAInstalled() {
|
||||||
void Worker::onIsmasResponseReceived(QJsonObject ismasResponse) {
|
QStringList const dcVersion = getDCVersion();
|
||||||
|
QString const deviceControllerVersionHW = dcVersion.first();
|
||||||
|
QString const deviceControllerVersionSW = dcVersion.last();
|
||||||
|
|
||||||
qInfo() << "IN ON_ISMAS_RESPONSE_RECEIVED" << QThread::currentThread()->objectName();
|
qInfo() << "CURRENT DC-HW-VERSION: " << deviceControllerVersionHW;
|
||||||
|
qInfo() << "CURRENT DC-SW-VERSION: " << deviceControllerVersionSW;
|
||||||
|
|
||||||
if (!ismasResponse.isEmpty()) {
|
QString const deviceControllerGitBlob = "N/A";
|
||||||
QStringList const keys = ismasResponse.keys();
|
QString const deviceControllerGitLastCommit = "N/A";
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_RESPONSE_RECEIVED,
|
|
||||||
QString("RECEIVED JSON WITH KEYS: ") + keys.join(","));
|
|
||||||
|
|
||||||
static QRegularExpression re("^REQ_ISMASPARAMETER.*");
|
PSAInstalled psaInstalled;
|
||||||
if(keys.indexOf(re) >= 0) {
|
QString printSysDir("/etc/psa_config");
|
||||||
m_waitForNewUpdates.stop(); // stop asking ISMAS for updates
|
QString tariffSysDir("/etc/psa_tariff");
|
||||||
|
QString absPathName;
|
||||||
|
|
||||||
// sanity check: cust_nr and machine_nr of PSA correct ?
|
if (m_zoneNr != 0) {
|
||||||
if (keys.contains("Dev_ID", Qt::CaseInsensitive)) {
|
QString const &n = QString("%1").arg(m_zoneNr).rightJustified(2, '0');
|
||||||
QJsonObject const devId = ismasResponse["Dev_ID"].toObject();
|
psaInstalled.tariff.name = QString("tariff%1.json").arg(n);
|
||||||
QStringList const keys = devId.keys();
|
absPathName = QDir::cleanPath(tariffSysDir + QDir::separator() + psaInstalled.tariff.name);
|
||||||
if (keys.contains("Custom_ID") && keys.contains("Device_ID")) {
|
psaInstalled.tariff.blob = m_gc.gitBlob(absPathName);
|
||||||
QJsonValue const c = devId.value("Custom_ID");
|
psaInstalled.tariff.size = getFileSize(absPathName);
|
||||||
QJsonValue const m = devId.value("Device_ID");
|
psaInstalled.tariff.zone = m_zoneNr;
|
||||||
int customerNr = c.toInt(-1);
|
|
||||||
int machineNr = m.toInt(-1);
|
|
||||||
if (customerNr != m_customerNr) {
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
|
||||||
m_statusDescription
|
|
||||||
= QString("CUSTOMER-NR (%1) != LOCAL CUSTOMER-NR (%2)")
|
|
||||||
.arg(customerNr).arg(m_customerNr);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (machineNr != m_machineNr) {
|
psaInstalled.tariff.project = "Szeged";
|
||||||
m_statusDescription
|
psaInstalled.tariff.info = "N/A";
|
||||||
= QString("MACHINE-NR (%1) != LOCAL MACHINE-NR (%2)")
|
psaInstalled.tariff.loadTime = "N/A"; // QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
|
||||||
.arg(machineNr).arg(m_machineNr);
|
psaInstalled.tariff.version = "N/A";
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: check if zone_nr is correct
|
|
||||||
|
|
||||||
if (keys.contains("Fileupload", Qt::CaseInsensitive)) {
|
psaInstalled.hw.linuxVersion = m_osVersion;
|
||||||
QJsonObject fileUpload = ismasResponse["Fileupload"].toObject();
|
psaInstalled.hw.cpuSerial = m_cpuSerial;
|
||||||
QJsonValue v = fileUpload.value("TRG");
|
|
||||||
if (!v.isNull() && !v.isUndefined()) {
|
|
||||||
QString const s = v.toString("");
|
|
||||||
if (s == "WAIT") {
|
|
||||||
m_ismasUpdateRequests = ISMAS_UPDATE_REQUESTS;
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS,
|
psaInstalled.dc.versionHW = deviceControllerVersionHW;
|
||||||
"DETECTED AVAILABLE ISMAS-DOWNLOAD");
|
psaInstalled.dc.versionSW = deviceControllerVersionSW;
|
||||||
|
psaInstalled.dc.gitBlob = "N/A";
|
||||||
|
psaInstalled.dc.gitLastCommit = "N/A";
|
||||||
|
psaInstalled.dc.size = -1;
|
||||||
|
|
||||||
QString const &data = m_ismasClient.updateOfPSAActivated();
|
psaInstalled.sw.raucVersion = m_raucVersion;
|
||||||
m_apismClient.onSendCmdEventToIsmas(data);
|
psaInstalled.sw.opkgVersion = m_opkgVersion;
|
||||||
|
psaInstalled.sw.atbQTVersion = m_atbqtVersion;
|
||||||
|
|
||||||
emit m_gc.ismasUpdatesAvailable();
|
psaInstalled.pluginVersion.deviceController = m_pluginVersionATBDeciceController;
|
||||||
} else {
|
psaInstalled.pluginVersion.ingenicoISelfCC = m_pluginVersionIngenicoISelf;
|
||||||
// TODO: enorm wichtig
|
psaInstalled.pluginVersion.mobilisisCalculatePrice = m_pluginVersionMobilisisCalc;
|
||||||
qCritical() << "DID NOT RECEIVE 'WAIT' BUT" << s;
|
psaInstalled.pluginVersion.mobilisisCalculatePriceConfigUi = m_pluginVersionMobilisisCalcConfig;
|
||||||
onTerminateUpdateProcess();
|
psaInstalled.pluginVersion.prmCalculatePrice = m_pluginVersionPrmCalc;
|
||||||
}
|
psaInstalled.pluginVersion.prmCalculatePriceConfigUi = m_pluginVersionPrmCalcConfig;
|
||||||
}
|
psaInstalled.pluginVersion.tcpZVT = m_pluginVersionTcpZvt;
|
||||||
} else {
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
psaInstalled.cash.name = "DC2C_cash.json";
|
||||||
m_statusDescription = "NO FILEUPLOAD KEY AVAILABLE";
|
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.cash.name);
|
||||||
return;
|
psaInstalled.cash.blob = m_gc.gitBlob(absPathName);
|
||||||
|
psaInstalled.cash.size = getFileSize(absPathName);
|
||||||
|
|
||||||
|
psaInstalled.conf.name = "DC2C_conf.json";
|
||||||
|
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.conf.name);
|
||||||
|
psaInstalled.conf.blob = m_gc.gitBlob(absPathName);
|
||||||
|
psaInstalled.conf.size = getFileSize(absPathName);
|
||||||
|
|
||||||
|
psaInstalled.device.name = "DC2C_device.json";
|
||||||
|
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.device.name);
|
||||||
|
psaInstalled.device.blob = m_gc.gitBlob(absPathName);
|
||||||
|
psaInstalled.device.size = getFileSize(absPathName);
|
||||||
|
|
||||||
|
for (int i=0; i < 32; ++i) {
|
||||||
|
QString const &n = QString("%1").arg(i+1).rightJustified(2, '0');
|
||||||
|
psaInstalled.print[i].name = QString("DC2C_print%1.json").arg(n);
|
||||||
|
absPathName = QDir::cleanPath(printSysDir + QDir::separator() + psaInstalled.print[i].name);
|
||||||
|
psaInstalled.print[i].blob = m_gc.gitBlob(absPathName);
|
||||||
|
psaInstalled.print[i].size = getFileSize(absPathName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return psaInstalled;
|
||||||
} else {
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_FAILURE;
|
|
||||||
m_statusDescription = "NO ISMAS RESPONSE AVAILABLE (EMPTY)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worker::onFinishUpdateProcess(bool changes) {
|
QString Worker::sendCmdSendVersionToIsmas() {
|
||||||
Q_UNUSED(changes);
|
|
||||||
|
|
||||||
qInfo() << "ON FINISH UPDATE PROCESS" << QThread::currentThread()->objectName();
|
|
||||||
// m_emergencyTimer.stop();
|
|
||||||
|
|
||||||
onSendCmdSendVersionToIsmas(); // final message to ISMAS
|
|
||||||
|
|
||||||
m_workerThread.quit();
|
|
||||||
QApplication::quit();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Worker::onTerminateUpdateProcess() {
|
|
||||||
qCritical() << "ON TERMINATE UPDATE PROCESS";
|
|
||||||
|
|
||||||
onSendCmdSendVersionToIsmas(); // final message to ISMAS
|
|
||||||
|
|
||||||
m_workerThread.quit();
|
|
||||||
QApplication::quit();
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::onSendCmdSendVersionToIsmas() {
|
|
||||||
|
|
||||||
QStringList const dcVersion = getDCVersion();
|
QStringList const dcVersion = getDCVersion();
|
||||||
QString const deviceControllerVersionHW = dcVersion.first();
|
QString const deviceControllerVersionHW = dcVersion.first();
|
||||||
@ -560,37 +782,8 @@ void Worker::onSendCmdSendVersionToIsmas() {
|
|||||||
psaInstalled.print[i].size = getFileSize(absPathName);
|
psaInstalled.print[i].size = getFileSize(absPathName);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString data = m_ismasClient.updateOfPSASendVersion(psaInstalled);
|
// QByteArray data = "#M=APISM#C=CMD_SENDVERSION#J=";
|
||||||
|
return m_ismasClient.updateOfPSASendVersion(psaInstalled);
|
||||||
// printf("data=%s\n", data.toStdString().c_str());
|
|
||||||
|
|
||||||
m_apismClient.onSendCmdSendVersionToIsmas(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::askIsmasForNewData() {
|
|
||||||
if (m_maintenanceMode) {
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_EMULATE_DATA_AVAILABLE;
|
|
||||||
QString data = m_ismasClient.setUpdatesAvailable();
|
|
||||||
m_apismClient.emulateUpdatesAvailable(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING;
|
|
||||||
//m_statusDescription = "Ask ISMAS IF NEW DATA AVAILABLE";
|
|
||||||
|
|
||||||
qInfo() << UpdateStatus(UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING,
|
|
||||||
QString("ASK ISMAS IF NEW DATA AVAILABLE") +
|
|
||||||
QString(" (%1)").arg(m_ismasUpdateRequests));
|
|
||||||
|
|
||||||
m_apismClient.requestAvailableIsmasUpdates();
|
|
||||||
|
|
||||||
if (--m_ismasUpdateRequests > 0) {
|
|
||||||
// if the timer is already running, it will be stopped and restarted.
|
|
||||||
m_waitForNewUpdates.start(10000);
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING;
|
|
||||||
} else {
|
|
||||||
m_updateStatus = UPDATE_STATUS::ISMAS_UPDATE_REQUEST_TIMEOUT;
|
|
||||||
onTerminateUpdateProcess();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************
|
/************************************************************************************************
|
||||||
@ -598,16 +791,28 @@ void Worker::askIsmasForNewData() {
|
|||||||
*/
|
*/
|
||||||
QDebug operator<< (QDebug debug, UpdateStatus status) {
|
QDebug operator<< (QDebug debug, UpdateStatus status) {
|
||||||
switch(status.m_updateStatus) {
|
switch(status.m_updateStatus) {
|
||||||
case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING:
|
case UPDATE_STATUS::UPDATE_PROCESS_SUCCESS:
|
||||||
debug << QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: ")
|
debug << QString("UPDATE_STATUS::UPDATE_PROCESS_SUCCESS: ")
|
||||||
<< status.m_statusDescription;
|
<< status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS:
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING:
|
||||||
debug << QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: ")
|
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING: ")
|
||||||
<< status.m_statusDescription;
|
<< status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST:
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE:
|
||||||
debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: ")
|
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE: ")
|
||||||
|
<< status.m_statusDescription;
|
||||||
|
break;
|
||||||
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_TIMEOUT:
|
||||||
|
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_: ")
|
||||||
|
<< status.m_statusDescription;
|
||||||
|
break;
|
||||||
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_SUCCESS:
|
||||||
|
debug << QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_SUCCESS: ")
|
||||||
|
<< status.m_statusDescription;
|
||||||
|
break;
|
||||||
|
case UPDATE_STATUS::GIT_FETCH_UPDATES:
|
||||||
|
debug << QString("UPDATE_STATUS::GIT_FETCH_UPDATES: ")
|
||||||
<< status.m_statusDescription;
|
<< status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
|
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
|
||||||
@ -653,16 +858,20 @@ QDebug operator<< (QDebug debug, UpdateStatus status) {
|
|||||||
|
|
||||||
QString& operator<< (QString& str, UpdateStatus status) {
|
QString& operator<< (QString& str, UpdateStatus status) {
|
||||||
switch(status.m_updateStatus) {
|
switch(status.m_updateStatus) {
|
||||||
case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING:
|
case UPDATE_STATUS::UPDATE_PROCESS_SUCCESS:
|
||||||
str = QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_PENDING: ");
|
str = QString("UPDATE_STATUS::UPDATE_PROCESS_SUCCESS: ");
|
||||||
str += status.m_statusDescription;
|
str += status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS:
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING:
|
||||||
str = QString("UPDATE_STATUS::ISMAS_UPDATE_REQUEST_SUCCESS: ");
|
str = QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_PENDING: ");
|
||||||
str += status.m_statusDescription;
|
str += status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST:
|
case UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_SUCCESS:
|
||||||
str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST: ");
|
str = QString("UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_SUCCESS: ");
|
||||||
|
str += status.m_statusDescription;
|
||||||
|
break;
|
||||||
|
case UPDATE_STATUS::GIT_FETCH_UPDATES:
|
||||||
|
str = QString("UPDATE_STATUS::GIT_FETCH_UPDATES: ");
|
||||||
str += status.m_statusDescription;
|
str += status.m_statusDescription;
|
||||||
break;
|
break;
|
||||||
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
|
case UPDATE_STATUS::GIT_FETCH_UPDATES_REQUEST_FAILURE:
|
||||||
|
96
worker.h
96
worker.h
@ -13,7 +13,6 @@
|
|||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "git/git_client.h"
|
#include "git/git_client.h"
|
||||||
#include "ismas/ismas_client.h"
|
#include "ismas/ismas_client.h"
|
||||||
#include "apism/apism_client.h"
|
|
||||||
|
|
||||||
#ifdef PTU5
|
#ifdef PTU5
|
||||||
#define SERIAL_PORT "ttymxc2"
|
#define SERIAL_PORT "ttymxc2"
|
||||||
@ -23,21 +22,31 @@
|
|||||||
|
|
||||||
|
|
||||||
enum class UPDATE_STATUS : quint8 {
|
enum class UPDATE_STATUS : quint8 {
|
||||||
ISMAS_EMULATE_DATA_AVAILABLE,
|
NOT_DEFINED,
|
||||||
ISMAS_UPDATE_REQUEST_PENDING,
|
STEP_OK,
|
||||||
ISMAS_UPDATE_REQUEST_FAILURE,
|
STEP_DONE,
|
||||||
ISMAS_UPDATE_REQUEST_TIMEOUT,
|
STEP_FAIL,
|
||||||
ISMAS_UPDATE_REQUEST_SUCCESS,
|
ISMAS_WAIT_STATE_CHECK_PENDING,
|
||||||
|
ISMAS_WAIT_STATE_CHECK_FAILURE,
|
||||||
|
ISMAS_WAIT_STATE_CHECK_TIMEOUT,
|
||||||
|
ISMAS_WAIT_STATE_CHECK_SUCCESS,
|
||||||
ISMAS_RESPONSE_RECEIVED,
|
ISMAS_RESPONSE_RECEIVED,
|
||||||
GIT_CHECKOUT_BRANCH_REQUEST,
|
BACKEND_CONNECTED,
|
||||||
|
BACKEND_NOT_CONNECTED,
|
||||||
|
UPDATE_TRIGGER_SET,
|
||||||
|
UPDATE_TRIGGER_NOT_SET_OR_WRONG,
|
||||||
|
GIT_CLONE_AND_CHECKOUT_SUCCESS,
|
||||||
|
GIT_CLONE_AND_CHECKOUT_FAILURE,
|
||||||
|
GIT_CHECKOUT_BRANCH,
|
||||||
GIT_CHECKOUT_BRANCH_REQUEST_FAILURE,
|
GIT_CHECKOUT_BRANCH_REQUEST_FAILURE,
|
||||||
GIT_CHECKOUT_BRANCH_NOT_EXISTS,
|
GIT_CHECKOUT_BRANCH_NOT_EXISTS,
|
||||||
GIT_CHECKOUT_BRANCH_CHECKOUT_ERROR,
|
GIT_CHECKOUT_BRANCH_CHECKOUT_ERROR,
|
||||||
GIT_FETCH_UPDATES_REQUEST,
|
GIT_FETCH_UPDATES,
|
||||||
GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
GIT_FETCH_UPDATES_REQUEST_FAILURE,
|
||||||
GIT_FETCH_UPDATES_REQUEST_SUCCESS,
|
GIT_FETCH_UPDATES_REQUEST_SUCCESS,
|
||||||
GIT_PULL_UPDATES_SUCCESS,
|
GIT_PULL_UPDATES_SUCCESS,
|
||||||
GIT_PULL_UPDATES_FAILURE,
|
GIT_PULL_UPDATES_FAILURE,
|
||||||
|
EXEC_OPKG_COMMAND,
|
||||||
EXEC_OPKG_COMMANDS,
|
EXEC_OPKG_COMMANDS,
|
||||||
EXEC_OPKG_COMMAND_FAILURE,
|
EXEC_OPKG_COMMAND_FAILURE,
|
||||||
EXEC_OPKG_COMMAND_SUCCESS,
|
EXEC_OPKG_COMMAND_SUCCESS,
|
||||||
@ -51,6 +60,8 @@ enum class UPDATE_STATUS : quint8 {
|
|||||||
JSON_UPDATE,
|
JSON_UPDATE,
|
||||||
JSON_UPDATE_FAILURE,
|
JSON_UPDATE_FAILURE,
|
||||||
JSON_UPDATE_SUCCESS,
|
JSON_UPDATE_SUCCESS,
|
||||||
|
UPDATE_PROCESS_SUCCESS,
|
||||||
|
UPDATE_PROCESS_FAILURE,
|
||||||
ISMAS_UPDATE_INFO_CONFIRM,
|
ISMAS_UPDATE_INFO_CONFIRM,
|
||||||
ISMAS_UPDATE_INFO_CONFIRM_FAILURE,
|
ISMAS_UPDATE_INFO_CONFIRM_FAILURE,
|
||||||
ISMAS_UPDATE_INFO_CONFIRM_SUCCESS,
|
ISMAS_UPDATE_INFO_CONFIRM_SUCCESS,
|
||||||
@ -63,7 +74,8 @@ struct UpdateStatus {
|
|||||||
UPDATE_STATUS m_updateStatus;
|
UPDATE_STATUS m_updateStatus;
|
||||||
QString m_statusDescription;
|
QString m_statusDescription;
|
||||||
|
|
||||||
explicit UpdateStatus(UPDATE_STATUS s, QString const &d)
|
explicit UpdateStatus(UPDATE_STATUS s = UPDATE_STATUS::NOT_DEFINED,
|
||||||
|
QString const &d = QString(""))
|
||||||
: m_updateStatus(s), m_statusDescription(d) {}
|
: m_updateStatus(s), m_statusDescription(d) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,10 +90,6 @@ class Worker : public QObject {
|
|||||||
|
|
||||||
hwinf *m_hw;
|
hwinf *m_hw;
|
||||||
WorkerThread m_workerThread;
|
WorkerThread m_workerThread;
|
||||||
QTimer m_startUpdateProcess;
|
|
||||||
QTimer m_emergencyTimer;
|
|
||||||
Update *m_update;
|
|
||||||
ApismClient m_apismClient;
|
|
||||||
int const m_customerNr;
|
int const m_customerNr;
|
||||||
QString const m_customerNrStr;
|
QString const m_customerNrStr;
|
||||||
int const m_machineNr;
|
int const m_machineNr;
|
||||||
@ -90,8 +98,9 @@ class Worker : public QObject {
|
|||||||
QString const m_branchName;
|
QString const m_branchName;
|
||||||
QString const m_customerRepositoryPath;
|
QString const m_customerRepositoryPath;
|
||||||
QString const m_customerRepository;
|
QString const m_customerRepository;
|
||||||
|
Update *m_update;
|
||||||
|
IsmasClient m_ismasClient;
|
||||||
GitClient m_gc;
|
GitClient m_gc;
|
||||||
bool m_maintenanceMode;
|
|
||||||
QString const m_osVersion;
|
QString const m_osVersion;
|
||||||
QString const m_atbqtVersion;
|
QString const m_atbqtVersion;
|
||||||
QString const m_cpuSerial;
|
QString const m_cpuSerial;
|
||||||
@ -107,12 +116,14 @@ class Worker : public QObject {
|
|||||||
|
|
||||||
int m_ismasUpdateRequests;
|
int m_ismasUpdateRequests;
|
||||||
QTimer m_waitForNewUpdates;
|
QTimer m_waitForNewUpdates;
|
||||||
IsmasClient m_ismasClient;
|
|
||||||
|
|
||||||
UPDATE_STATUS m_updateStatus;
|
UpdateStatus m_updateStatus;
|
||||||
QString m_statusDescription;
|
|
||||||
|
|
||||||
void executeOpkgCommand(QString opkgCommand);
|
QStringList m_filesToUpdate;
|
||||||
|
bool m_updateProcessRunning;
|
||||||
|
int m_displayIndex;
|
||||||
|
|
||||||
|
bool executeOpkgCommand(QString opkgCommand);
|
||||||
QString getOsVersion() const;
|
QString getOsVersion() const;
|
||||||
QString getATBQTVersion() const;
|
QString getATBQTVersion() const;
|
||||||
QString getCPUSerial() const;
|
QString getCPUSerial() const;
|
||||||
@ -124,21 +135,31 @@ class Worker : public QObject {
|
|||||||
qint64 getFileSize(QString const &fileName) const;
|
qint64 getFileSize(QString const &fileName) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const QString UPDATE_STEP_OK;
|
||||||
|
static const QString UPDATE_STEP_DONE;
|
||||||
|
static const QString UPDATE_STEP_FAIL;
|
||||||
|
static const QString UPDATE_STEP_SUCCESS;
|
||||||
|
|
||||||
explicit Worker(hwinf *hw,
|
explicit Worker(hwinf *hw,
|
||||||
int customerNr, // 281
|
int customerNr, // 281
|
||||||
int machineNr,
|
int machineNr,
|
||||||
int zoneNr,
|
int zoneNr,
|
||||||
QString branchName,
|
QString branchName,
|
||||||
QString workingDir = ".",
|
QString workingDir = ".",
|
||||||
bool maintenanceMode = false,
|
|
||||||
bool dryRun = false,
|
bool dryRun = false,
|
||||||
QObject *parent = nullptr,
|
QObject *parent = nullptr,
|
||||||
char const *serialInterface = SERIAL_PORT,
|
char const *serialInterface = SERIAL_PORT,
|
||||||
char const *baudrate = "115200");
|
char const *baudrate = "115200");
|
||||||
~Worker();
|
~Worker();
|
||||||
void quit() { return m_workerThread.quit(); }
|
|
||||||
|
|
||||||
static int read1stLineOfFile(QString fileName);
|
IsmasClient &getIsmasClient() { return m_ismasClient; }
|
||||||
|
IsmasClient const &getIsmasClient() const { return m_ismasClient; }
|
||||||
|
|
||||||
|
bool updateProcessRunning() const { return m_updateProcessRunning; }
|
||||||
|
|
||||||
|
int machineNr() const { return m_machineNr; }
|
||||||
|
int customerNr() const { return m_customerNr; }
|
||||||
|
int zoneNr() const { return m_zoneNr; }
|
||||||
|
|
||||||
//friend QDebug operator<<(QDebug debug, Worker const &w) {
|
//friend QDebug operator<<(QDebug debug, Worker const &w) {
|
||||||
// Q_UNUSED(w);
|
// Q_UNUSED(w);
|
||||||
@ -150,24 +171,29 @@ public:
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void handleChangedFiles(QStringList);
|
void appendText(QString, QString);
|
||||||
void summarizeUpload(QStringList);
|
void showErrorMessage(QString title, QString description);
|
||||||
void summarizeRepositoryStatus();
|
void setProgress(quint8);
|
||||||
void sendCmdSendVersionToIsmas();
|
void stopStartTimer();
|
||||||
void finishUpdateProcess(bool changes);
|
void restartExitTimer();
|
||||||
void terminateUpdateProcess();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onIsmasResponseReceived(QJsonObject ismasResponse);
|
void update();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void askIsmasForNewData();
|
bool backendConnected();
|
||||||
void onSendCmdSendVersionToIsmas();
|
bool updateTriggerSet();
|
||||||
void onSummarizeRepositoryStatus();
|
bool customerEnvironment();
|
||||||
void onFinishUpdateProcess(bool changes);
|
bool filesToUpdate();
|
||||||
void onTerminateUpdateProcess();
|
bool updateFiles(quint8 percent);
|
||||||
void onSummarizeUpload(QStringList);
|
bool syncCustomerRepositoryAndFS();
|
||||||
void onHandleChangedFiles(QStringList);
|
bool sendIsmasLastVersionNotification();
|
||||||
|
bool saveLogFile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
PSAInstalled getPSAInstalled();
|
||||||
|
QString sendCmdSendVersionToIsmas();
|
||||||
|
void privateUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WORKER_H_INCLUDED
|
#endif // WORKER_H_INCLUDED
|
||||||
|
Loading…
x
Reference in New Issue
Block a user