#if 0 #include "ApismClient.h" #include "support/VendingData.h" #include "support/PersistentData.h" #include "support/utils.h" #include "ATBHMIconfig.h" #include "support/DBusControllerInterface.h" #include #include #include #include #include #include #include #include // 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) , retryCounter(0) , programMode(PROGRAM_MODE::IDLE) { this->apismTcpSendClient = new ApismTcpClient("127.0.0.1", "7777", this); this->apismTcpRequestResponseClient = new ApismTcpClient("127.0.0.1", "7778", this); this->apismTcpRequestResponseClient->setResponseTimeout(30000); connect(apismTcpRequestResponseClient, &ApismTcpClient::receivedData, this, &ApismClient::onReceivedResponse); connect(apismTcpRequestResponseClient, &ApismTcpClient::responseTimeout, this, &ApismClient::onRequestResponseClientResponseTimeout); connect(apismTcpRequestResponseClient, &ApismTcpClient::connectionClosedByRemoteHost, this, &ApismClient::onRequestResponseClientConnectionClosedByRemoteHost); connect(apismTcpSendClient, &ApismTcpClient::responseTimeout, this, &ApismClient::onSendClientResponseTimeout); //connect(apismTcpSendClient, &ApismTcpClient::receivedData, // this, &ApismClient::onSendClientResponseTimeout); // 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(); // connect(&m_socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), // this, SLOT(onSocketError(&QAbstractSocket::SocketError))); this->init_sc_dbus(); } ApismClient::~ApismClient() { } void ApismClient::restartApism() { QProcess::startDetached("/bin/systemctl", {"restart", "apism"}); } void ApismClient::onChangedProgramModeToSELL() { this->retryCounter = 0; this->programMode = PROGRAM_MODE::SELL; this->sendSelfTest(); } void ApismClient::onChangedProgramModeToOOO() { this->retryCounter = 0; this->programMode = PROGRAM_MODE::OOO; } void ApismClient::onChangedProgramModeToIDLE() { this->retryCounter = 0; this->programMode = PROGRAM_MODE::IDLE; } void ApismClient::onChangedProgramModeToSERVICE() { this->retryCounter = 0; this->programMode = PROGRAM_MODE::SERVICE; } void ApismClient::onWokeUp(uchar from) { Q_UNUSED(from) //this->restartApism(); //this->sendSelfTest(); } //void ApismClient::onReadyRead() { // parse APISM response // QByteArray data = m_socket.readAll(); // qCritical() << "APISM-RESPONSE = (" << endl << data << endl << ")"; //} void ApismClient::sendTransaction(const VendingData *vendingData) { QScopedPointer transferData(new ISMAS::TransferData()); PAYMENT_VARIANTS::TYPE paymentType = vendingData->getParameter("PaymentType").value(); ////////////////////// 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("TransactionDelivery")) { QVariant delVariant = vendingData->getParameter("TransactionDelivery"); transferData->result.delivery = delVariant.toJsonValue(); transferData->result.insert("DELIVERY", transferData->result.delivery); resultSet = true; } if (vendingData->hasParameter("TransactionResult")) { QVariant resVariant = vendingData->getParameter("TransactionResult"); transferData->result.result = resVariant.toJsonValue(); transferData->result.insert("RESULT", transferData->result.result); resultSet = true; } if (vendingData->hasParameter("ErrorCode")) { QVariant ecVariant = vendingData->getParameter("ErrorCode"); transferData->result.errorCode = ecVariant.toJsonValue(); transferData->result.insert("ERRORCODE", transferData->result.errorCode); resultSet = true; } if (vendingData->hasParameter("ErrorDescription")) { QVariant emsgVariant = vendingData->getParameter("ErrorDescription"); 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 & accountDataHash) { QScopedPointer accountData(new ISMAS::AccountData()); // set JSON for ISMAS message: accountData->coinBox.UID = QUuid::createUuid().toString(QUuid::WithoutBraces); // .mid(0, 8) accountData->insert("UID", accountData->coinBox.UID); accountData->coinBox.ChangeNumber = QJsonValue(accountDataHash["AccountingNumber"].toInt()); 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::getISODateTimeWithMsAndOffset(accountDataHash["accountStartTime"])); 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); // set persistent account data: this->persistentData->setParameter("CoinboxChangeNumber", accountDataHash["AccountingNumber"]); this->persistentData->setParameter("AccountStartTime", accountDataHash["accountStartTime"]); this->persistentData->clearForNewAccount(); persistentData->serializeToFile(); this->dbus->finishedBackgroundTask("ACCOUNT"); } void ApismClient::sendEvent(const ATBMachineEvent* machineEvent) { QScopedPointer 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); } 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 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); } 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 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(vendingData->getUintParameter("PRICE_INFO_GROSS"))); transferData->startAction.insert("RATE_H", static_cast(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; this->retryCounter = 0; 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 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); } void ApismClient::sendSelfTest() { this->currentRequest = ISMAS::REQUEST::SELF; QByteArray data = "#M=APISM#C=REQ_SELF#J={}"; this->apismTcpRequestResponseClient->sendData(data); } void ApismClient::sendRequestParameter() { this->currentRequest = ISMAS::REQUEST::PARAMETER; QByteArray data = "#M=APISM#C=REQ_ISMASPARAMETER#J={}"; this->apismTcpRequestResponseClient->sendData(data); } void ApismClient::sendMininformPingRequest() { this->currentRequest = ISMAS::REQUEST::PING; this->retryCounter = 0; QByteArray data = "#M=APISM#C=REQ_Ping#J={\"281\":\"PING\"}"; this->apismTcpRequestResponseClient->sendData(data); } void ApismClient::onReceivedResponse(QByteArray response) { // 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(); // workaround for REQ_SELF and offline if (this->currentRequest == ISMAS::REQUEST::SELF) { if (response.contains("Connecting...")) { qCritical() << " -> Connecting..."; return; } if (response.contains("ISMAS is offline")) { this->restartApism(); qCritical() << " -> Workaround: restart APISM"; return; } } if (response.contains("ISMAS is offline")) { this->handleISMASOfflineResponseError(); return; } else { this->handleISMASResponseError(); return; } } QJsonObject rootObject = responseDoc.object(); QStringList rootObjectKeys = rootObject.keys(); // DEBUG qCritical() << "ApismClient::onReceivedResponse(): objects: " << rootObjectKeys; // results to: // ApismClient::onReceivedResponse(): objects: ("REQ_START#60044_Response", "Response") if(rootObjectKeys.indexOf(QRegularExpression("^REQ_START.*")) >= 0) { this->retryCounter = 0; this->private_handleMininformStartResponse(rootObject["Response"].toObject()); } else if(rootObjectKeys.indexOf(QRegularExpression("^REQ_STOP.*")) >= 0) { this->retryCounter = 0; this->private_handleMininformStopResponse(rootObject["Response"].toObject()); } else if(rootObjectKeys.indexOf(QRegularExpression("^CMD_GET_APISMSTATUS.*")) >= 0) { this->retryCounter = 0; this->private_handleReqSelfResponse(rootObject["CMD_GET_APISMSTATUS_RESPONSE#0"].toObject()); } else if(rootObjectKeys.indexOf(QRegularExpression("^REQ_ISMASPARAMETER.*")) >= 0) { this->retryCounter = 0; this->private_handleParameterResponse(rootObject["Response"].toObject()); } else if(rootObjectKeys.indexOf(QRegularExpression("^REQ_PING.*")) >= 0) { this->retryCounter = 0; this->private_handleReqPingResponse(rootObject["PING"].toObject()); } else if(rootObjectKeys.indexOf(QRegularExpression("^error")) >= 0) { // handle error objects this->private_handleErrorResponse(rootObject["error"].toString()); } 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::PARAMETER: emit this->sendReqParameterResponse(nsApismInterface::RESULT_STATE::ERROR_BACKEND, QJsonObject()); break; } this->currentRequest = ISMAS::REQUEST::NO_REQUEST; } void ApismClient::handleISMASOfflineResponseError() { nsApismInterface::RESULT_STATE resultState; if (this->retryCounter < 50 && this->programMode == PROGRAM_MODE::SELL) { resultState = nsApismInterface::RESULT_STATE::ERROR_RETRY; this->retryCounter++; } else { resultState = nsApismInterface::RESULT_STATE::ERROR_BACKEND; this->retryCounter = 0; } switch (this->currentRequest) { case ISMAS::REQUEST::NO_REQUEST: qCritical() << "ApismClient::onReceivedResponse() for unknown Request: " << currentRequest; break; case ISMAS::REQUEST::START: emit this->sendMininformStartResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::STOP: emit this->sendMininformStopResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::PING: emit this->sendMininformPingResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::SELF: emit this->sendReqSelfResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::PARAMETER: emit this->sendReqParameterResponse(resultState, QJsonObject()); break; } this->currentRequest = ISMAS::REQUEST::NO_REQUEST; // note: this does not work here, because a new request within this error handling method // must use a new socket connection! // This does not work with an allready open socket connection. /* Communication to APISM must be in the following way: * 1) establish socket connection * 2) send your request to this socket * 3) wait for a possible answer * 4) receive the answer * 5) close socket connection * * => a request can only be sent to apsim if the socket is closed! * => apism (socket) is blocked systemwide until socket is closed! * => */ //this->sendSelfTest(); } void ApismClient::private_handleErrorResponse(QString errorString) { qCritical() << "------------------------------------------------------"; qCritical() << "ApismClient::private_handleErrorResponse(" << errorString << ")"; qCritical() << " this->retryCounter = " << this->retryCounter; qCritical() << "------------------------------------------------------"; this->handleISMASOfflineResponseError(); } /* {\r\n \"REQ_START#53365_Response\": {\r\n \"Aknoledge\": \"OK\"\r\n }, \r\n \"Response\": {\r\n \"Result\": \"ERR:Ung�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::PARAMETER: emit this->sendReqParameterResponse(nsApismInterface::RESULT_STATE::ERROR_TIMEOUT, QJsonObject()); break; } this->currentRequest = ISMAS::REQUEST::NO_REQUEST; } void ApismClient::onRequestResponseClientConnectionClosedByRemoteHost() { nsApismInterface::RESULT_STATE resultState; if (this->retryCounter < 50 && this->programMode == PROGRAM_MODE::SELL) { resultState = nsApismInterface::RESULT_STATE::ERROR_RETRY; this->retryCounter++; } else { resultState = nsApismInterface::RESULT_STATE::ERROR_BACKEND; this->retryCounter = 0; } switch (this->currentRequest) { case ISMAS::REQUEST::NO_REQUEST: qCritical() << "ApismClient::onRequestResponseClientConnectionClosedByRemoteHost() for unknown Request: " << currentRequest; break; case ISMAS::REQUEST::START: emit this->sendMininformStartResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::STOP: emit this->sendMininformStopResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::PING: emit this->sendMininformPingResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::SELF: emit this->sendReqSelfResponse(resultState, QJsonObject()); break; case ISMAS::REQUEST::PARAMETER: emit this->sendReqParameterResponse(resultState, QJsonObject()); 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) { bool ismasConnected = response["ISMAS"].toBool(); QString brokerConnectedString = response["Broker"].toString(); qCritical() << "ApismClient::handleReqSelfResponse() " << endl << " ismasConnected = " << ismasConnected << endl << " brokerConnectedString = " << brokerConnectedString; /* possible values: "Restart connection" * "Connected" * "NOT CONNECTED" */ if (brokerConnectedString == "NOT CONNECTED") { qCritical() << "ApismClient: \"NOT CONNECTED\": restart APISM"; this->restartApism(); } 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_handleParameterResponse(QJsonObject response) { emit this->sendReqParameterResponse(nsApismInterface::RESULT_STATE::SUCCESS, response); } /*********************************************************************************************** * dbus */ int ApismClient::init_sc_dbus() { #if defined (ARCH_PTU4) this->dbus = new DBusControllerInterface("eu.atb.ptu", "/systemcontrol", QDBusConnection::systemBus(), 0); #elif defined (ARCH_PTU5) this->dbus = new DBusControllerInterface("eu.atb.ptu.systemcontrol", "/systemcontrol", QDBusConnection::systemBus(), 0); #else this->dbus = new DBusControllerInterface("eu.atb.ptu", "/systemcontrol", QDBusConnection::sessionBus(), 0); #endif if (!dbus->isValid()) { QString errorString = QDBusError::errorString(dbus->lastError().type()); qCritical() << errorString; if (dbus->lastError().isValid()){ qCritical() << "last error is valid."; } qCritical() << "message: " << dbus->lastError().message(); qCritical() << "SystemController is not valid."; return 0; } if (!dbus->connection().isConnected()) { qCritical() << "SystemController is not connected."; return 0; } connect(this->dbus, SIGNAL(wokeUpFrom(uchar)), this, SLOT(onWokeUp(uchar))); return 1; } /************************************************************************************************ * 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::PARAMETER: debug << QString("ISMAS::REQUEST::PARAMETER"); 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::PARAMETER: str = QString("ISMAS::REQUEST::PARAMETER"); break; } return str; } #endif