#include "ismas/ismas_client.h" #include "utils.h" #include <cstring> #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 ######################## # Spec vom 27.10.2023: # U0010 -> %-Werte # U0001 -> 100% # U0003 -> "FAIL" # U0002 -> "" (OK -> WAIT state reset) # ISMAS -> "WAIT" ######################## # # $1: EVENT: U0001 update finished: 100% # U0002 reset TRG # U0003 error # U0010 for update process # $2: PERCENT : "only for ISMAS: 0-100%", # $3: RESULTCODE : "only for ISMAS", # 0: Success # 1: no Update nessesary # 2: Backup failed # 3: Package error/ Wrong package # 4: Install Error # $4: STEP : "running step (only for us): update_psa...", # $5: STEP_RESULT : "error and result text", # $6: VERSION : "opkg and conf info; what will be updated" # #endif #include <QDateTime> #include <QDebug> void IsmasClient::printDebugMessage(int port, QString const &clientIP, int clientPort, QString const &message) { #if 0 Q_UNUSED(port); Q_UNUSED(clientIP); Q_UNUSED(clientPort); Q_UNUSED(message); #else qDebug().noquote() << "\n" << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n" << "hostname ........" << "127.0.0.1" << "\n" << "port ............" << port << "\n" << "local address ..." << clientIP << "\n" << "local port ......" << clientPort << "\n" << message; #endif } void IsmasClient::printInfoMessage(int port, QString const &clientIP, int clientPort, QString const &message) { #if 0 Q_UNUSED(port); Q_UNUSED(clientIP); Q_UNUSED(clientPort); Q_UNUSED(message); #else qInfo().noquote() << "\n" << "SEND-REQUEST-RECEIVE-RESPONSE ..." << "\n" << "hostname ........" << "127.0.0.1" << "\n" << "port ............" << port << "\n" << "local address ..." << clientIP << "\n" << "local port ......" << clientPort << "\n" << message; #endif } 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; int maxfdp1; fd_set rset; fd_set wset; setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)); // no reliable, but does not harm, as we use select() as well setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); setsockopt(sockfd, SOL_SOCKET, SO_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 loop = 0; int bytesWritten = 0; while (bytesWritten < bytesToWrite) { errno = 0; FD_ZERO(&wset); FD_SET(sockfd, &wset); maxfdp1 = sockfd + 1; tv.tv_sec = 60; /* 60 secs timeout for read and write -> APISM cuts the connection after 30s */ tv.tv_usec = 0; int const w = select(maxfdp1, NULL, &wset, NULL, &tv); if (w < 0) { // error if (errno == EINTR) { printErrorMessage(port, clientIP, clientPort, QString("INTERRUPTED BY SIGNAL (1) (") + strerror(errno) + ")"); continue; } else { printErrorMessage(port, clientIP, clientPort, QString("SELECT-ERROR (WRITE) %1(").arg(loop) + strerror(errno) + ")"); ::close(sockfd); return std::nullopt; } } else if (w == 0) { // timeout printErrorMessage(port, clientIP, clientPort, QString("SELECT-TIMEOUT (WRITE) %1(").arg(loop) + strerror(errno) + ")"); if (++loop < 10) { QThread::msleep(500); continue; } ::close(sockfd); return std::nullopt; } else if (w > 0) { int n = ::sendto(sockfd, buf+bytesWritten, bytesToWrite-bytesWritten, 0, NULL, 0); if (n >= 0) { bytesWritten += n; } else { if (errno == EWOULDBLOCK) { if (++loop < 10) { QThread::msleep(500); continue; } printErrorMessage(port, clientIP, clientPort, QString("WRITE TIMEOUT %1(").arg(loop) + strerror(errno) + ")"); ::close(sockfd); return std::nullopt; } else if (errno == EINTR) { printErrorMessage(port, clientIP, clientPort, QString("WRITE 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 + ">>>"); loop = 0; bzero(buf, sizeof(buf)); int bytesToRead = sizeof(buf)-1; int bytesRead = 0; while (bytesRead < bytesToRead) { errno = 0; FD_ZERO(&rset); FD_SET(sockfd, &rset); maxfdp1 = sockfd + 1; tv.tv_sec = 60; /* 60 secs timeout for read and write */ tv.tv_usec = 0; QString const selectStart = QDateTime::currentDateTime().toString(Qt::ISODateWithMs); int const r = select(maxfdp1, &rset, NULL, NULL, &tv); if (r < 0) { // error if (errno == EINTR) { printErrorMessage(port, clientIP, clientPort, QString("INTERRUPTED BY SIGNAL (2) (") + strerror(errno) + ")"); continue; } else { printErrorMessage(port, clientIP, clientPort, QString("SELECT-ERROR (READ) %1(").arg(loop) + strerror(errno) + ")"); ::close(sockfd); return std::nullopt; } } else if (r == 0) { // timeout printErrorMessage(port, clientIP, clientPort, QString("SELECT-TIMEOUT (READ) %1(").arg(loop) + strerror(errno) + ")"); if (++loop < 10) { QThread::msleep(500); continue; } ::close(sockfd); return std::nullopt; } else if (r > 0) { if (FD_ISSET(sockfd, &rset)) { int n = ::recvfrom(sockfd, buf+bytesRead, bytesToRead-bytesRead, 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) + ") START AT" + selectStart + " NOW " + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); ::close(sockfd); return std::nullopt; } else if (n < 0) { if (errno == EWOULDBLOCK) { // check just in case if (++loop < 10) { QThread::msleep(500); continue; } printErrorMessage(port, clientIP, clientPort, QString("READ TIMEOUT %1(").arg(loop) + 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.contains("RECORD")) { // RECORD SAVED or RECORD WRITE ABORTED printInfoMessage(port, clientIP, clientPort, QString("IGNORED '") + response + "' 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, int percent, int resultCode, char const *step, char const *step_result, char const *version) { char buf[1024]; memset(buf, 0, sizeof(buf)); QString const ts = QDateTime::currentDateTime().toString(Qt::ISODateWithMs); snprintf(buf, sizeof(buf)-1, "{" "\"REASON\":\"SW_UP\"," "\"TIMESTAMP\":\"%s\"," "\"EVENT_ID\":\"0\"," "\"EVENT\":\"%s\"," "\"EVENTSTATE\":1," "\"PARAMETER\": {" "\"PERCENT\" : %d," "\"RESULTCODE\" : %d," "\"STEP\" : \"%s\"," "\"STEP_RESULT\" : \"%s\"," "\"VERSION\" : \"%s\"" "}" "}", ts.toStdString().c_str(), event, percent, resultCode, step, step_result, version); return buf; } QString IsmasClient::errorBackendNotConnected(QString const &info, QString const &version) { return updateNewsToIsmas("U0003", m_progressInPercent, RESULT_CODE::ISMAS_NO_CONNECTION_ERROR, "CHECK BACKEND CONNECTIVITY", info.toStdString().c_str(), version.toStdString().c_str()); } QString IsmasClient::errorGitClone(QString const &info, QString const &version) { return updateNewsToIsmas("U0003", m_progressInPercent, RESULT_CODE::GIT_CLONE_ERROR, "CLONE CUSTOMER REPOSITORY FAILED", 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::rsyncFile(QString const &info, QString const &version) { return updateNewsToIsmas("U0010", m_progressInPercent, RESULT_CODE::SUCCESS, "RSYNC FILE", info.toStdString().c_str(), version.toStdString().c_str()); } QString IsmasClient::updateTriggerSet(QString const &info, QString const &version) { 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::ISMAS_TRIGGER_ERROR, "CHECK UPDATE TRIGGER", info.toStdString().c_str(), version.toStdString().c_str()); } QString IsmasClient::updateOfPSASendVersion(PSAInstalled const &psa) { //static int const constexpr SIZE = 4096*8; static char buf[4096*2]; memset(buf, 0, sizeof(buf)); // local data="#M=APISM#C=CMD_SENDVERSION#J= snprintf(buf, sizeof(buf)-1, "{" "\"VERSION_INFO\" : {" "\"REASON\":\"%s\"," "\"CREATED\":\"%s\"," "\"HASH\":\"%s\"" "}," "\"TARIFF\" : {" "\"VERSION\" : \"%s\"," "\"PROJECT\" : \"%s\"," "\"ZONE\" : %d," "\"INFO\" : \"%s\"," "\"BLOB\" : \"%s\"," "\"LAST-COMMIT\" : \"%s\"," "\"SIZE\" : %d," "\"LOADED\" : \"%s\"" "}," "\"OPKG_COMMANDS\" : {" "\"BLOB\" : \"%s\"," "\"LAST-COMMIT\" : \"%s\"," "\"SIZE\" : %d," "\"LOADED\" : \"%s\"" "}," "\"JSON\" : {" "\"DC2C_CASH\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_CONF\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_DEVICE\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_01\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_02\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_03\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_04\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_05\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_06\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_07\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_08\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_09\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_10\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_11\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_12\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_13\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_14\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_15\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_16\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_17\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_18\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_19\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_20\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_21\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_22\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_23\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_24\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_25\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_26\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_27\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_28\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_29\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_30\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_31\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}," "\"DC2C_PRINT_32\" : {" "\"BLOB\" : \"%s\"," "\"SIZE\" : %d" "}" "}," "\"HARDWARE\" : {" "\"DEVICES\" : [\"PTU5\", \"DC\", \"PRINTER\", \"BNA\"]" "}," "\"OS\" : {" "\"Linux\": \"%s\"" "}," "\"CONFIG\" : {" "\"PTU5\" : {" "\"CPU_SERIAL\" : \"%s\"" "}," "\"DC\" : {" "\"HW-VERSION\" : \"%s\"," "\"SW-VERSION\" : \"%s\"," "\"SIZE\" : %d," "\"GITBLOB\" : \"%s\"," "\"GITLASTCOMMIT\" : \"%s\"" "}," "\"PRINTER\" : {" "}," "\"BNA\" : {" "}" "}," "\"SOFTWARE\": {" "\"APISM\" : {" "\"VERSION\" : \"%s\"" "}," "\"ATBQT\" : {" "\"VERSION\" : \"%s\"" "}," "\"ATB-UPDATE-TOOL\" : {" "\"VERSION\" : \"%s\"" "}" "}," "\"PLUGINS\" : {" "\"libATBDeviceControllerPlugin.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libIngenicoISelf_CCPlugin.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libMOBILISIS_CalculatePricePlugin.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libMOBILISIS_CalculatePricePlugin_ConfigUi.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libPRM_CalculatePricePlugin.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libPRM_CalculatePricePlugin_ConfigUi.so\" : {" "\"VERSION\" : \"%s\"" "}," "\"libTCP_ZVT_CCPlugin.so\" : {" "\"VERSION\" : \"%s\"" "}" "}" "}", psa.versionInfo.reason.toStdString().c_str(), psa.versionInfo.created.toStdString().c_str(), psa.versionInfo.lastCommit.toStdString().c_str(), psa.tariff.version.toStdString().c_str(), psa.tariff.project.toStdString().c_str(), psa.tariff.zone, psa.tariff.info.toStdString().c_str(), psa.tariff.blob.toStdString().c_str(), psa.tariff.lastCommit.toStdString().c_str(), psa.tariff.size, psa.tariff.loadTime.toStdString().c_str(), psa.opkg.blob.toStdString().c_str(), psa.opkg.lastCommit.toStdString().c_str(), psa.opkg.size, psa.opkg.loadTime.toStdString().c_str(), psa.cash.blob.toStdString().c_str(), psa.cash.size, psa.conf.blob.toStdString().c_str(), psa.conf.size, psa.device.blob.toStdString().c_str(), psa.device.size, psa.print[0].blob.toStdString().c_str(), psa.print[0].size, psa.print[1].blob.toStdString().c_str(), psa.print[1].size, psa.print[2].blob.toStdString().c_str(), psa.print[2].size, psa.print[3].blob.toStdString().c_str(), psa.print[3].size, psa.print[4].blob.toStdString().c_str(), psa.print[4].size, psa.print[5].blob.toStdString().c_str(), psa.print[5].size, psa.print[6].blob.toStdString().c_str(), psa.print[6].size, psa.print[7].blob.toStdString().c_str(), psa.print[7].size, psa.print[8].blob.toStdString().c_str(), psa.print[8].size, psa.print[9].blob.toStdString().c_str(), psa.print[9].size, psa.print[10].blob.toStdString().c_str(), psa.print[10].size, psa.print[11].blob.toStdString().c_str(), psa.print[11].size, psa.print[12].blob.toStdString().c_str(), psa.print[12].size, psa.print[13].blob.toStdString().c_str(), psa.print[13].size, psa.print[14].blob.toStdString().c_str(), psa.print[14].size, psa.print[15].blob.toStdString().c_str(), psa.print[15].size, psa.print[16].blob.toStdString().c_str(), psa.print[16].size, psa.print[17].blob.toStdString().c_str(), psa.print[17].size, psa.print[18].blob.toStdString().c_str(), psa.print[18].size, psa.print[19].blob.toStdString().c_str(), psa.print[19].size, psa.print[20].blob.toStdString().c_str(), psa.print[20].size, psa.print[21].blob.toStdString().c_str(), psa.print[21].size, psa.print[22].blob.toStdString().c_str(), psa.print[22].size, psa.print[23].blob.toStdString().c_str(), psa.print[23].size, psa.print[24].blob.toStdString().c_str(), psa.print[24].size, psa.print[25].blob.toStdString().c_str(), psa.print[25].size, psa.print[26].blob.toStdString().c_str(), psa.print[26].size, psa.print[27].blob.toStdString().c_str(), psa.print[27].size, psa.print[28].blob.toStdString().c_str(), psa.print[28].size, psa.print[29].blob.toStdString().c_str(), psa.print[29].size, psa.print[30].blob.toStdString().c_str(), psa.print[30].size, psa.print[31].blob.toStdString().c_str(), psa.print[31].size, psa.hw.linuxVersion.toStdString().c_str(), psa.hw.cpuSerial.toStdString().c_str(), psa.dc.versionHW.toStdString().c_str(), psa.dc.versionSW.toStdString().c_str(), psa.dc.size, psa.dc.gitBlob.toStdString().c_str(), psa.dc.gitLastCommit.toStdString().c_str(), psa.sw.apismVersion.toStdString().c_str(), psa.sw.atbQTVersion.toStdString().c_str(), psa.sw.atbUpdateToolVersion.toStdString().c_str(), psa.pluginVersion.deviceController.toStdString().c_str(), psa.pluginVersion.ingenicoISelfCC.toStdString().c_str(), psa.pluginVersion.mobilisisCalculatePrice.toStdString().c_str(), psa.pluginVersion.mobilisisCalculatePriceConfigUi.toStdString().c_str(), psa.pluginVersion.prmCalculatePrice.toStdString().c_str(), psa.pluginVersion.prmCalculatePriceConfigUi.toStdString().c_str(), psa.pluginVersion.tcpZVT.toStdString().c_str()); qInfo() << buf; return buf; } #if 0 // prepare QString IsmasClient::sendLastVersion(UPDATE_COMPONENT updateComponent, PSAInstalled const &psa) { static char buf[4096*2]; memset(buf, 0, sizeof(buf)); switch (updateComponent) { case UPDATE_COMPONENT::TARIFF: snprintf(buf, sizeof(buf)-1, "{" "\"VERSION_INFO\" : {" "\"UPDATE_REASON\":\"%s\"," "\"CREATED\":\"%s\"," "\"GIT_COMMIT\":\"%s\"" "}," "\"TARIFF\" : {" "\"VERSION\" : \"%s\"," "\"PROJECT\" : \"%s\"," "\"ZONE\" : %d," "\"INFO\" : \"%s\"," "\"SIZE\" : %d\"" "}," "}", psa.tariff.versionInfo.reason.toStdString().c_str(), psa.tariff.versionInfo.created.toStdString().c_str(), psa.tariff.versionInfo.lastCommit.toStdString().c_str(), psa.tariff.version.toStdString().c_str(), psa.tariff.project.toStdString().c_str(), psa.tariff.zone, psa.tariff.info.toStdString().c_str(), psa.tariff.size); break; case UPDATE_COMPONENT::SOFTWARE_ATBQT: break; case UPDATE_COMPONENT::SOFTWARE_APISM: break; case UPDATE_COMPONENT::SOFTWARE_ATB_UPDATE_TOOL: break; case UPDATE_COMPONENT::CONFIG_PTU5_CPU_SERIAL: break; case UPDATE_COMPONENT::CONFIG_DEVICE_CONTROLLER: break; case UPDATE_COMPONENT::CONFIG_PRINTER: break; case UPDATE_COMPONENT::CONFIG_BNA: break; case UPDATE_COMPONENT::PLUGIN_ATB_DEVICE_CONTROLLER: break; case UPDATE_COMPONENT::PLUGIN_INGENICO_CC: break; case UPDATE_COMPONENT::PLUGIN_MOBILISIS_CALC_PRICE: break; case UPDATE_COMPONENT::PLUGIN_MOBILISIS_CALC_PRICE_UI: break; case UPDATE_COMPONENT::PLUGIN_PRM_CALC_PRICE: break; case UPDATE_COMPONENT::PLUGIN_PRM_CALC_PRICE_UI: break; case UPDATE_COMPONENT::PLUGIN_TCP_ZVT_CC: break; case UPDATE_COMPONENT::OPKG_COMMANDS: break; case UPDATE_COMPONENT::HARDWARE_DEVICES: break; case UPDATE_COMPONENT::OS: break; case UPDATE_COMPONENT::DC2C_CASH_JSON: break; case UPDATE_COMPONENT::DC2C_CONF_JSON: break; case UPDATE_COMPONENT::DC2C_DEVICE_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT01_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT02_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT03_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT04_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT05_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT06_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT07_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT08_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT09_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT10_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT11_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT12_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT13_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT14_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT15_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT16_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT17_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT18_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT19_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT20_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT21_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT22_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT23_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT24_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT25_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT26_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT27_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT28_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT29_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT30_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT31_JSON: break; case UPDATE_COMPONENT::DC2C_PRINT32_JSON: break; } qInfo() << buf; return buf; } #endif QString IsmasClient::updateOfPSAContinues(QString currentStage, QString currentStageInfo, QString const &version) { return updateNewsToIsmas("U0010", m_progressInPercent, RESULT_CODE::SUCCESS, currentStage.toStdString().c_str(), currentStageInfo.toStdString().c_str(), version.toStdString().c_str()); } 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 = 100; return updateNewsToIsmas("U0001", m_progressInPercent, RESULT_CODE::SUCCESS, "UPDATE SUCCESS", "update process succeeded", version.toStdString().c_str()); } QString IsmasClient::sanityCheckFailed(int resultCode, QString reason, QString const &version) { return updateNewsToIsmas("U0003", m_progressInPercent, resultCode, "SANITY-CHECK-FAILED", reason.toStdString().c_str(), version.toStdString().c_str()); } QString IsmasClient::jsonParseFailed(int resultCode, QString reason, QString const &version) { return updateNewsToIsmas("U0003", m_progressInPercent, resultCode, "JSON-PARSE-ERROR", reason.toStdString().c_str(), version.toStdString().c_str()); } std::optional<QString> IsmasClient::finalResult(int resultCode, QString reason, QString const &version) { Q_UNUSED(resultCode); Q_UNUSED(reason); Q_UNUSED(version); /* m_progressInPercent = 100; if (resultCode == RESULT_CODE::SUCCESS) { return updateNewsToIsmas("U0002", m_progressInPercent, resultCode, "FINAL-UPDATE-RESULT", reason.toStdString().c_str(), version.toStdString().c_str()); } if (resultCode == RESULT_CODE::INSTALL_ERROR) { return updateNewsToIsmas("U0003", m_progressInPercent, resultCode, "FINAL-UPDATE-RESULT", reason.toStdString().c_str(), version.toStdString().c_str()); } */ return std::nullopt; } QString IsmasClient::updateOfPSAFailed(int resultCode, QString step, QString reason, QString const &version) { return updateNewsToIsmas("U0003", m_progressInPercent, resultCode, step.toStdString().c_str(), reason.toStdString().c_str(), version.toStdString().c_str()); } char const *IsmasClient::reason[REASON::ENTRIES] = { "TIME-TRIGGERED", "SERVICE", "DEV-TEST" }; QString IsmasClient::getReasonForLastSendVersion() { QString const &parentName = Utils::getParentName(); if (parentName == "ATBQT") { return reason[REASON::SERVICE]; } if (parentName == "systemd") { return reason[REASON::TIME_TRIGGERED]; } return reason[REASON::DEV_TEST]; }