Compare commits

..

No commits in common. "8d528f0f554ec071eb77d8cdf4a20476c059b767" and "86c996d7acd3331c80f58583f936acea639d3b95" have entirely different histories.

4 changed files with 69 additions and 161 deletions

View File

@ -137,12 +137,7 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
so_linger.l_onoff = 1; so_linger.l_onoff = 1;
so_linger.l_linger = 0; so_linger.l_linger = 0;
int maxfdp1;
fd_set rset;
fd_set wset;
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)); setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger));
// no reliable, but does not harm, as we use select() as well
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
int flag = 1; int flag = 1;
@ -156,56 +151,24 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
int loop = 0; int loop = 0;
int bytesWritten = 0; int bytesWritten = 0;
while (bytesWritten < bytesToWrite) { while (bytesWritten < bytesToWrite) {
errno = 0; int n = ::sendto(sockfd, buf+bytesWritten, bytesToWrite-bytesWritten, 0, NULL, 0);
FD_ZERO(&wset); if (n >= 0) {
FD_SET(sockfd, &wset); bytesWritten += n;
maxfdp1 = sockfd + 1; } else {
tv.tv_sec = 60; /* 60 secs timeout for read and write -> APISM cuts the connection after 30s */ if (errno == EWOULDBLOCK) {
tv.tv_usec = 0; if (++loop < 10) {
QThread::msleep(500);
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; 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;
} }
} }
} }
@ -225,66 +188,33 @@ IsmasClient::sendRequestReceiveResponse(int port, QString const &request) {
int bytesRead = 0; int bytesRead = 0;
while (bytesRead < bytesToRead) { while (bytesRead < bytesToRead) {
errno = 0; errno = 0;
FD_ZERO(&rset); int n = ::recvfrom(sockfd, buf+bytesRead, bytesToRead-bytesRead,
FD_SET(sockfd, &rset); 0, NULL, NULL);
maxfdp1 = sockfd + 1; if (n > 0) { //
tv.tv_sec = 60; /* 60 secs timeout for read and write */ bytesRead += n;
tv.tv_usec = 0; } else
if (n == 0) {
int const r = select(maxfdp1, &rset, NULL, NULL, &tv); // The return value will be 0 when the peer has performed an orderly shutdown.
if (r < 0) { // error printErrorMessage(port, clientIP, clientPort,
QString("PEER CLOSED CONNECTION (") + strerror(errno) + ")");
::close(sockfd);
return std::nullopt;
} else
if (n < 0) {
if (errno == EWOULDBLOCK) {
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) { if (errno == EINTR) {
printErrorMessage(port, clientIP, clientPort, printErrorMessage(port, clientIP, clientPort,
QString("INTERRUPTED BY SIGNAL (2) (") + strerror(errno) + ")"); QString("INTERRUPTED BY SIGNAL (2) (") + strerror(errno) + ")");
continue; 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) + ")");
::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;
}
}
} }
} }

View File

@ -8,8 +8,7 @@ Command::Command(QString const &command, int start_timeout, int finish_timeout)
: m_command(command.trimmed()) : m_command(command.trimmed())
, m_commandResult("") , m_commandResult("")
, m_waitForStartTimeout(start_timeout) , m_waitForStartTimeout(start_timeout)
, m_waitForFinishTimeout(finish_timeout) , m_waitForFinishTimeout(finish_timeout) {
, m_exitCode(-1) {
} }
QString Command::getCommandResult() const { QString Command::getCommandResult() const {
@ -63,7 +62,7 @@ bool Command::execute(QString workingDirectory, QStringList args) {
if (p->waitForFinished(m_waitForFinishTimeout)) { if (p->waitForFinished(m_waitForFinishTimeout)) {
//qDebug() << "PROCESS" << m_command << "FINISHED"; //qDebug() << "PROCESS" << m_command << "FINISHED";
if (p->exitStatus() == QProcess::NormalExit) { if (p->exitStatus() == QProcess::NormalExit) {
if ((m_exitCode = p->exitCode()) == 0) { if (p->exitCode() == 0) {
return true; return true;
} else { } else {
qCritical() << "EXECUTED" << m_command << "with code" << p->exitCode(); qCritical() << "EXECUTED" << m_command << "with code" << p->exitCode();

View File

@ -16,17 +16,15 @@ class Command : public QObject {
QString m_commandResult; QString m_commandResult;
int m_waitForStartTimeout; int m_waitForStartTimeout;
int m_waitForFinishTimeout; int m_waitForFinishTimeout;
int m_exitCode;
public: public:
explicit Command(QString const &command, explicit Command(QString const &command,
int start_timeout = 100000, int start_timeout = 100000,
int finish_timeout = 100000); int finish_timeout = 100000);
QString getCommandResult() const; QString getCommandResult() const;
QString command() const { return m_command; }
bool execute(QString workingDirectory, QStringList args = QStringList()); bool execute(QString workingDirectory, QStringList args = QStringList());
int exitCode() const { return m_exitCode; }
private slots: private slots:
void readyReadStandardOutput(); void readyReadStandardOutput();

View File

@ -497,14 +497,12 @@ bool Worker::backendConnected() {
return false; return false;
} }
#define CHECK_UPDATE_TRIGGER_SET "Check update trigger ..."
bool Worker::updateTriggerSet() { bool Worker::updateTriggerSet() {
if (m_withoutIsmasDirectPort) { // useful for testing if (m_withoutIsmasDirectPort) { // useful for testing
return true; return true;
} }
emit appendText("\n" CHECK_UPDATE_TRIGGER_SET); emit appendText("\nUpdate trigger set ...");
QString triggerValue(""); QString triggerValue("");
for (int repeat = 0; repeat < 50; ++repeat) { for (int repeat = 0; repeat < 50; ++repeat) {
@ -520,7 +518,7 @@ bool Worker::updateTriggerSet() {
QString msg = result.value(); QString msg = result.value();
qInfo() << "REPEAT" << repeat << "APISM RESPONSE (" << msg << ")"; qInfo() << "REPEAT" << repeat << "APISM RESPONSE" << msg;
QJsonParseError parseError; QJsonParseError parseError;
QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError)); QJsonDocument document(QJsonDocument::fromJson(msg.toUtf8(), &parseError));
@ -539,7 +537,7 @@ bool Worker::updateTriggerSet() {
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", emit showErrorMessage("check update trigger",
QString("invalid json ") + msg.mid(0, 20)); QString("invalid json ") + msg.mid(0, 20));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
if (!document.isObject()) { if (!document.isObject()) {
@ -552,25 +550,13 @@ bool Worker::updateTriggerSet() {
m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.jsonParseFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", QString("not a json object") + msg); emit showErrorMessage("check update trigger", QString("not a json object") + msg);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
progress += 1; progress += 1;
setProgress(progress); setProgress(progress);
QJsonObject obj = document.object(); QJsonObject obj = document.object();
// always look for an 'error' first
if (obj.contains("error")) {
progress += 1;
setProgress(progress);
QString value = obj.value("error").toString();
emit showErrorMessage("check update trigger", QString("REPEAT %1 error=<").arg(repeat) + value + ">");
qInfo() << "REPEAT" << repeat << "In updateTriggerSet() error=<"
<< value << ">";
QThread::sleep(6);
continue;
}
// sanity check: cust_nr and machine_nr of PSA correct ? // sanity check: cust_nr and machine_nr of PSA correct ?
// note: this check has to be done here, as the cust_nr and the machine_nr // note: this check has to be done here, as the cust_nr and the machine_nr
// of the PSA are sent by ISMAS. // of the PSA are sent by ISMAS.
@ -593,7 +579,7 @@ bool Worker::updateTriggerSet() {
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
if (machineNr != m_machineNr) { if (machineNr != m_machineNr) {
@ -606,7 +592,7 @@ bool Worker::updateTriggerSet() {
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
@ -621,7 +607,7 @@ bool Worker::updateTriggerSet() {
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
} else { } else {
@ -633,7 +619,7 @@ bool Worker::updateTriggerSet() {
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
} else { } else {
@ -645,7 +631,7 @@ bool Worker::updateTriggerSet() {
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
progress += 1; progress += 1;
@ -678,28 +664,19 @@ bool Worker::updateTriggerSet() {
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.updateTriggerSet(m_updateStatus.m_statusDescription, "")); m_ismasClient.updateTriggerSet(m_updateStatus.m_statusDescription, ""));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_DONE); emit replaceLast("Update trigger set ...", UPDATE_STEP_OK);
return true; return true;
} else
if (QRegExp("\\s*").exactMatch(triggerValue)) { // check for whitespace
stopProgressLoop();
int progress = (m_mainWindow->progressValue()/10) + 10;
progress += 1;
setProgress(progress);
emit showErrorMessage("check update trigger", "empty update-trigger");
QThread::sleep(6);
continue;
} else { } else {
// if the download-button once has the wrong value, it will never recover // if the download-button once has the wrong value, it will never recover
setProgress(100); setProgress(100);
m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE, m_updateStatus = UpdateStatus(UPDATE_STATUS::ISMAS_WAIT_STATE_CHECK_FAILURE,
QString("TRIGGER-VALUE=<") + triggerValue + "> NOT 'WAIT'"); QString("TRIGGER-VALUE ") + triggerValue + " NOT 'WAIT'");
IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT, IsmasClient::sendRequestReceiveResponse(IsmasClient::APISM::DB_PORT,
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
return false; return false;
} }
} else { } else {
@ -710,7 +687,7 @@ bool Worker::updateTriggerSet() {
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false; return false;
} }
@ -722,7 +699,7 @@ bool Worker::updateTriggerSet() {
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false; return false;
} }
@ -734,10 +711,20 @@ bool Worker::updateTriggerSet() {
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR, m_ismasClient.sanityCheckFailed(IsmasClient::RESULT_CODE::INSTALL_ERROR,
m_updateStatus.m_statusDescription)); m_updateStatus.m_statusDescription));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_FAIL);
emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription); emit showErrorMessage("check update trigger", m_updateStatus.m_statusDescription);
return false; return false;
} }
if (obj.contains("error")) {
progress += 1;
setProgress(progress);
QString value = obj.value("error").toString();
emit showErrorMessage("check update trigger", QString("REPEAT %1 error=<").arg(repeat) + value + ">");
qInfo() << "REPEAT" << repeat << "In updateTriggerSet() error=<"
<< value << ">";
QThread::sleep(6);
}
} else { } else {
stopProgressLoop(); stopProgressLoop();
int progress = (m_mainWindow->progressValue()/10) + 10; int progress = (m_mainWindow->progressValue()/10) + 10;
@ -756,7 +743,7 @@ bool Worker::updateTriggerSet() {
QString("#M=APISM#C=CMD_EVENT#J=") + QString("#M=APISM#C=CMD_EVENT#J=") +
m_ismasClient.errorUpdateTrigger(m_updateStatus.m_statusDescription, "")); m_ismasClient.errorUpdateTrigger(m_updateStatus.m_statusDescription, ""));
emit replaceLast(CHECK_UPDATE_TRIGGER_SET, UPDATE_STEP_FAIL); emit replaceLast("Update trigger set ...", UPDATE_STEP_OK);
return false; return false;
} }
@ -932,16 +919,10 @@ bool Worker::updateFiles(quint8 percent) {
} }
bool Worker::syncCustomerRepositoryAndFS() { bool Worker::syncCustomerRepositoryAndFS() {
// this step is currently needed only for updating tariff-files
setProgress(0); setProgress(0);
emit appendText("\nSync customer environment with filesystem ..."); emit appendText("\nSync customer environment with filesystem ...");
if (QDir(m_customerRepository).exists()) { if (QDir(m_customerRepository).exists()) {
if (QDir::setCurrent(m_customerRepository)) { if (QDir::setCurrent(m_customerRepository)) {
Command md("bash");
if (!md.execute(m_customerRepository,
QStringList() << "-c" << "mkdir -p /etc/psa_config /etc/psa_update /etc/dc /etc/psa_tariff")) {
qCritical() << "COULD NOT EXECUTE '" << md.command() << "' exitCode=(" << md.exitCode() << ")";
}
int progress = 10; int progress = 10;
setProgress(progress); setProgress(progress);
QString const params("-vv " QString const params("-vv "
@ -972,7 +953,7 @@ bool Worker::syncCustomerRepositoryAndFS() {
} }
} else { } else {
Utils::printCriticalErrorMsg(QString("CMD ") + cmd + " FAILED: " Utils::printCriticalErrorMsg(QString("CMD ") + cmd + " FAILED: "
+ c.getCommandResult() + QString(" EXIT_CODE=(%1)").arg(c.exitCode())); + c.getCommandResult());
error = true; error = true;
} }
} }