Compare commits

..

17 Commits

Author SHA1 Message Date
1897e8237a Add watcher for switching on/off modem 2024-11-13 15:02:14 +01:00
d5693cb2b1 Merge branch 'master' into palanga-switch-terminal-on-off 2024-11-13 14:18:45 +01:00
d3b1046a9f onCCWakeGpioChanged():
Use commands credit_switchWake/switchPower to reboot cc-terminal.
2024-11-13 13:28:04 +01:00
a98ddbdb85 Changed file name to check for cc-terminal rebbot to /run/powerctrl_cc. 2024-11-13 13:27:13 +01:00
91a0f88cd9 hwapi::onCCWakeGpioChanged():
when switching cc-terminal off, send 0 to watch-file (watched by a
	filesystem watcher).
	when switching cc-terminal on, send 1 to watch-file (watched by a
	filesystem watcher).
2024-11-11 16:20:15 +01:00
c31b38917a Use QSettings to get watch.txt file path.
onCCWakeGpioChanged():

	remove obsolete code.
2024-11-08 12:06:19 +01:00
fe1351fcca switching on/off modem seems to be enough 2024-11-07 16:09:20 +01:00
c337b6e50e hwapi::onCCWakeGpioChanged():
start implementation of slot for fileSystemWatcher.
	Seems to be enough to start only the modem, as the cc-terminal
	is connected to the modem.
2024-11-07 14:14:58 +01:00
821a6e63bf Connect fileSystemWatcher. 2024-11-07 14:14:25 +01:00
73b2dec85e Added fileSystemWatcher to check if cc-terminal has to switched on/off. 2024-11-07 14:12:02 +01:00
dd29fb0762 datif: command 112: accecpt 40ct coin value ("Stadtmünze" Kirchdorf) 2024-11-06 10:09:12 +01:00
c9e5834e29 Merge branch 'proposal_detect_obsolete_data' 2024-10-22 12:26:40 +02:00
8fa6d40a0c Merge branch 'proposal_detect_obsolete_data' of git.mimbach49.de:GerhardHoffmann/DCLibraries into proposal_detect_obsolete_data 2024-10-22 12:25:24 +02:00
3e7f71899c loadRecDataFromFrame():
Move coinAttached from error-state to normal debug output.
2024-10-21 16:16:26 +02:00
1cc14e9a4c Add some debug out-put (in error case). 2024-10-17 12:41:31 +02:00
5c9578ebef Minor: debug output (commented out) 2024-10-17 12:40:37 +02:00
b024e34b82 writeToSerial():
Write to serial line in one call as before.
2024-10-16 13:21:33 +02:00
4 changed files with 258 additions and 22 deletions

View File

@@ -63,7 +63,8 @@ V4.0 6.9.2023: activating DC-Bootloader in slve-lib (SM)
#include "shared_mem_buffer.h"
#include "runProc.h"
#include "interfaces.h"
#include <QScopedPointer>
#include <QFileSystemWatcher>
/*
* select Plugin Type here
@@ -98,7 +99,7 @@ V4.0 6.9.2023: activating DC-Bootloader in slve-lib (SM)
//#define THIS_IS_CA_MASTER
class QFileSystemWatcher;
class QSharedMemory;
class DownloadThread;
class ReportingThread;
@@ -115,7 +116,13 @@ private:
QSharedMemory *m_sharedMem;
ReportingThread *m_reportingThread;
DownloadThread *m_downloadThread;
//QTimer *hwapi_triggerBL;
QScopedPointer<QFileSystemWatcher> m_fileSystemWatcher;
QString m_powerctrl_cc;
QString m_powerctrl_modem;
private slots:
void onCCWakeGpioChanged(QString const &file);
public:
explicit hwapi(QObject *parent = nullptr);

View File

@@ -42,28 +42,23 @@ void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength)
CatSerial->clear();
QByteArray buffer(data);
int bytesToWrite = buffer.size();
while (bytesToWrite > 0 && !buffer.isEmpty()) {
int bytesWritten = CatSerial->write(buffer);
if (bytesWritten != -1) {
bytesToWrite -= bytesWritten;
buffer = buffer.right(bytesWritten);
} else {
if (bytesWritten == -1) {
qCritical() << __func__ << ":" << __LINE__
<< QString("ERROR %1 for sending %2").arg(CatSerial->errorString()).arg(data.toHex(':').constData());
CatSerial->clearError();
qCritical() << __func__ << ":" << __LINE__ << "cleared error on serial line. returning ...";
return;
}
}
CatSerial->flush();
writeCount += 1;
// only for debugging
// if ((unsigned int)data.constData()[2] == 31) { // request dynamic data
// qCritical() << __func__ << ":" << __LINE__ << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs)
// << "write cmd" << (unsigned int)data.constData()[2];
//}
} else {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR sending" << data.toHex(':') << "port is not open";

View File

@@ -483,6 +483,76 @@ void T_datif::StoredRecData()
gpi_storeLastResult(res);
}
static void dump(T_moduleCondition const *modCond) {
qCritical() << QString("modCond->ram %1 (%2)").arg(modCond->ram).arg(modCond->ram, 0, 16);
qCritical() << QString("modCond->intEe %1 (%2)").arg(modCond->intEe).arg(modCond->intEe, 0, 16);
qCritical() << QString("modCond->extEe %1 (%2)").arg(modCond->extEe).arg(modCond->extEe, 0, 16);
qCritical() << QString("modCond->rtc %1 (%2)").arg(modCond->rtc).arg(modCond->rtc, 0, 16);
qCritical() << QString("modCond->boardHw %1 (%2)").arg(modCond->boardHw).arg(modCond->boardHw, 0, 16);
qCritical() << QString("modCond->printer %1 (%2)").arg(modCond->printer).arg(modCond->printer, 0, 16);
qCritical() << QString("modCond->modem %1 (%2)").arg(modCond->modem).arg(modCond->modem, 0, 16);
qCritical() << QString("modCond->signal %1 (%2)").arg(modCond->signal).arg(modCond->signal, 0, 16);
qCritical() << QString("modCond->regist %1 (%2)").arg(modCond->regist).arg(modCond->regist, 0, 16);
qCritical() << QString("modCond->mdbBus %1 (%2)").arg(modCond->mdbBus).arg(modCond->mdbBus, 0, 16);
qCritical() << QString("modCond->coinChecker %1 (%2)").arg(modCond->coinChecker).arg(modCond->coinChecker, 0, 16);
qCritical() << QString("modCond->coinEscrow %1 (%2)").arg(modCond->coinEscrow).arg(modCond->coinEscrow, 0, 16);
qCritical() << QString("modCond->mifareReader %1 (%2)").arg(modCond->mifareReader).arg(modCond->mifareReader, 0, 16);
qCritical() << QString("modCond->creditTerm %1 (%2)").arg(modCond->creditTerm).arg(modCond->creditTerm, 0, 16);
qCritical() << QString("modCond->coinReject %1 (%2)").arg(modCond->coinReject).arg(modCond->coinReject, 0, 16);
qCritical() << QString("modCond->coinSafe %1 (%2)").arg(modCond->coinSafe).arg(modCond->coinSafe, 0, 16);
qCritical() << QString("modCond->billSafe %1 (%2)").arg(modCond->billSafe).arg(modCond->billSafe, 0, 16);
qCritical() << QString("modCond->voltage %1 (%2)").arg(modCond->voltage).arg(modCond->voltage, 0, 16);
qCritical() << QString("modCond->temper %1 (%2)").arg(modCond->temper).arg(modCond->temper, 0, 16);
qCritical() << QString("modCond->poweronTest %1 (%2)").arg(modCond->poweronTest).arg(modCond->poweronTest, 0, 16);
qCritical() << QString("modCond->doorState %1 (%2)").arg(modCond->doorState).arg(modCond->doorState, 0, 16);
qCritical() << QString("modCond->doorWasOpened %1 (%2)").arg(modCond->doorWasOpened).arg(modCond->doorWasOpened, 0, 16);
qCritical() << QString("modCond->changer %1 (%2)").arg(modCond->changer).arg(modCond->changer, 0, 16);
qCritical() << QString("modCond->coinBlocker %1 (%2)").arg(modCond->coinBlocker).arg(modCond->coinBlocker, 0, 16);
qCritical() << QString("modCond->billReader %1 (%2)").arg(modCond->billReader).arg(modCond->billReader, 0, 16);
qCritical() << QString("modCond->ResetReason %1 (%2)").arg(modCond->ResetReason).arg(modCond->ResetReason, 0, 16);
qCritical() << QString("modCond->allModulesChecked %1 (%2)").arg(modCond->allModulesChecked).arg(modCond->allModulesChecked, 0, 16);
qCritical() << QString("modCond->alarmState %1 (%2)").arg(modCond->alarmState).arg(modCond->alarmState, 0, 16);
qCritical() << QString("modCond->fuses %1 (%2)").arg(modCond->fuses).arg(modCond->fuses, 0, 16);
}
static void dump(T_dynamicCondition const *dynCond) {
qCritical() << QString("dynCond->allDoorsDebounced %1 (%2)").arg((unsigned char)dynCond->allDoorsDebounced).arg((unsigned char)dynCond->allDoorsDebounced, 0, 16);
qCritical() << QString("dynCond->openedAuthorized %1 (%2)").arg((unsigned char)dynCond->openedAuthorized).arg((unsigned char)dynCond->openedAuthorized, 0, 16);
qCritical() << QString("dynCond->CBinDebounced %1 (%2)").arg((unsigned char)dynCond->CBinDebounced).arg((unsigned char)dynCond->CBinDebounced, 0, 16);
qCritical() << QString("dynCond->upperDoor %1 (%2)").arg((unsigned char)dynCond->upperDoor).arg((unsigned char)dynCond->upperDoor, 0, 16);
qCritical() << QString("dynCond->middleDoor %1 (%2)").arg((unsigned char)dynCond->middleDoor).arg((unsigned char)dynCond->middleDoor, 0, 16);
qCritical() << QString("dynCond->lowerDoor %1 (%2)").arg((unsigned char)dynCond->lowerDoor).arg((unsigned char)dynCond->lowerDoor, 0, 16);
qCritical() << QString("dynCond->middleDoor %1 (%2)").arg((unsigned char)dynCond->middleDoor).arg((unsigned char)dynCond->middleDoor, 0, 16);
qCritical() << QString("dynCond->coinAttached %1 (%2)").arg((unsigned char)dynCond->coinAttached).arg((unsigned char)dynCond->coinAttached, 0, 16);
qCritical() << QString("dynCond->billBox %1 (%2)").arg((unsigned char)dynCond->billBox).arg((unsigned char)dynCond->billBox, 0, 16);
qCritical() << QString("dynCond->modeAbrech %1 (%2)").arg((unsigned char)dynCond->modeAbrech).arg((unsigned char)dynCond->modeAbrech, 0, 16);
qCritical() << QString("dynCond->onAlarm %1 (%2)").arg((unsigned char)dynCond->onAlarm).arg((unsigned char)dynCond->onAlarm, 0, 16);
qCritical() << QString("dynCond->nowCardTest %1 (%2)").arg((unsigned char)dynCond->nowCardTest).arg((unsigned char)dynCond->nowCardTest, 0, 16);
qCritical() << QString("dynCond->nowPayment %1 (%2)").arg((unsigned char)dynCond->nowPayment).arg((unsigned char)dynCond->nowPayment, 0, 16);
qCritical() << QString("dynCond->lastMifCardType %1 (%2)").arg((unsigned char)dynCond->lastMifCardType).arg((unsigned char)dynCond->lastMifCardType, 0, 16);
qCritical() << QString("dynCond->lastSDoorState %1 (%2)").arg(dynCond->lastSDoorState).arg(dynCond->lastSDoorState, 0, 16);
qCritical() << QString("dynCond->lastVDoorState %1 (%2)").arg(dynCond->lastVDoorState).arg(dynCond->lastVDoorState, 0, 16);
qCritical() << QString("dynCond->lastCBstate %1 (%2)").arg(dynCond->lastCBstate).arg(dynCond->lastCBstate, 0, 16);
qCritical() << QString("dynCond->paymentInProgress %1 (%2)").arg((unsigned char)dynCond->paymentInProgress).arg((unsigned char)dynCond->paymentInProgress, 0, 16);
qCritical() << QString("dynCond->U_Batt %1 (%2)").arg(dynCond->U_Batt).arg(dynCond->U_Batt, 0, 16);
qCritical() << QString("dynCond->nrCoinsInBox %1 (%2)").arg(dynCond->nrCoinsInBox).arg(dynCond->nrCoinsInBox, 0, 16);
qCritical() << QString("dynCond->amountInBox %1 (%2)").arg(dynCond->amountInBox).arg(dynCond->amountInBox, 0, 16);
qCritical() << QString("dynCond->totalTransVolume %1 (%2)").arg(dynCond->totalTransVolume).arg(dynCond->totalTransVolume, 0, 16);
qCritical() << QString("dynCond->totalNrOfVends %1 (%2)").arg(dynCond->totalNrOfVends).arg(dynCond->totalNrOfVends, 0, 16);
qCritical() << QString("dynCond->resultOfLastTemplPrint %1 (%2)").arg((unsigned char)dynCond->resultOfLastTemplPrint).arg((unsigned char)dynCond->resultOfLastTemplPrint, 0, 16);
qCritical() << QString("dynCond->lastPrinterStatus %1 (%2)").arg(dynCond->lastPrinterStatus).arg(dynCond->lastPrinterStatus, 0, 16);
qCritical() << QString("dynCond->startupTestIsRunning %1 (%2)").arg(dynCond->startupTestIsRunning).arg(dynCond->startupTestIsRunning, 0, 16);
qCritical() << QString("dynCond->totalNrOfCuts %1 (%2)").arg(dynCond->totalNrOfCuts).arg(dynCond->totalNrOfCuts, 0, 16);
qCritical() << QString("dynCond->nextAccountNumber %1 (%2)").arg(dynCond->nextAccountNumber).arg(dynCond->nextAccountNumber, 0, 16);
qCritical() << QString("dynCond->nrOfBillsInBox %1 (%2)").arg(dynCond->nrOfBillsInBox).arg(dynCond->nrOfBillsInBox, 0, 16);
qCritical() << QString("dynCond->UbatAtLastPrint %1 (%2)").arg(dynCond->UbatAtLastPrint).arg(dynCond->UbatAtLastPrint, 0, 16);
}
char T_datif::loadRecDataFromFrame()
{
// is called even with wrong received data in order to speed up the process (stop waiting for response)
@@ -556,12 +626,86 @@ char T_datif::loadRecDataFromFrame()
readCount = writeCount;
if (readSource != myDCIF->getReadSource()) {
qCritical() << __func__ << ":" << __LINE__ << ": ERROR length" << RdDleng << ", ignore data"
<< QByteArray((char const *)receivedData, RdDleng).toHex(':');
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
qCritical() << __func__ << ":" << __LINE__ << "would be interpretated as" << readSource << myDCIF->getReadSource();
return 0;
} else {
// only for debugging
// qCritical() << __func__ << ":" << __LINE__ << QDateTime::currentDateTime().time().toString(Qt::ISODateWithMs) << readSource << myDCIF->getReadSource();
if (readSource == 30) {
T_moduleCondition const *modCond = reinterpret_cast<T_moduleCondition const *>(receivedData);
if(modCond->rtc >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E002 (modCond->rtc >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->printer == 200 || modCond->printer == 201) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E020 (modCond->printer == 200 || modCond->printer == 201)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->printer == 202) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E018 (modCond->printer == 202)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->coinBlocker >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E025 (modCond->coinBlocker >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->mdbBus >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E034 (modCond->mdbBus >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->intEe >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E011 (modCond->intEe >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->voltage >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E003 (modCond->voltage >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->changer >= 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E026 (modCond->changer >= 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->coinSafe == 201) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E007 (modCond->coinSafe == 201)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (modCond->coinSafe == 200) {
dump(modCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E009 (modCond->coinSafe == 200)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
}
if (readSource == 31) {
T_dynamicCondition const *dynCond = reinterpret_cast<T_dynamicCondition const *>(receivedData);
if (dynCond->modeAbrech > 0) {
dump(dynCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E011 (dynCond->modeAbrech > 0)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (dynCond->nowCardTest > 0) {
dump(dynCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E072 (dynCond->nowCardTest > 0)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
if (dynCond->startupTestIsRunning > 0) {
dump(dynCond);
qCritical() << __func__ << ":" << __LINE__ << ": ERROR E073 (dynCond->startupTestIsRunning > 0)"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
}
}
} else {
qCritical() << __func__ << ":" << __LINE__ << QString(": ERROR readCount + 1 != writeCount: %1 != %2").arg(readCount + 1).arg(writeCount);
@@ -569,6 +713,19 @@ char T_datif::loadRecDataFromFrame()
<< QByteArray((char const *)receivedData, RdDleng).toHex(':');
qCritical() << __func__ << ":" << __LINE__ << "would be interpretated as" << readSource << myDCIF->getReadSource();
if (readSource == 30) {
T_moduleCondition const *modCond = reinterpret_cast<T_moduleCondition const *>(receivedData);
dump(modCond);
}
if (readSource == 31) {
T_dynamicCondition const *dynCond = reinterpret_cast<T_dynamicCondition const *>(receivedData);
dump(dynCond);
if (dynCond->coinAttached > 0) {
qCritical() << __func__ << ":" << __LINE__ << ": dynCond->coinAttached"
<< QByteArray(reinterpret_cast<char const *>(receivedData), RdDleng).toHex(':');
}
}
readCount = writeCount;
return 0;
}
@@ -1048,7 +1205,7 @@ char T_datif::loadRecDataFromFrame()
uit2=0;
}
if (uit2==3 || uit2==5 || uit2==10 || uit2==20 || uit2==50 || uit2==100 || uit2==200 || uit2==500)
if (uit2==3 || uit2==5 || uit2==10 || uit2==20 || uit2==40 || uit2==50 || uit2==100 || uit2==200 || uit2==500)
{
// valid coin
if ((newInsertedAmount != lastInsertedAmount) || uit2>0 )

View File

@@ -15,6 +15,8 @@
#include <cstring>
#include <QThread>
#include <QDebug>
#include <QFileSystemWatcher>
#include <QSettings>
static uint32_t hwapi_lastStartAmount;
@@ -35,6 +37,7 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
qCritical() << " hwapi::hwapi() APP_EXTENDED_VERSION:" << APP_EXTENDED_VERSION;
qCritical() << "hwapi::hwapi() APP_EXTENDED_VERSION_LIB:" << APP_EXTENDED_VERSION_LIB;
m_fileSystemWatcher.reset();
// create or attach shared memory segment
m_sharedMem = SharedMem::getShm(sizeof(SharedMem));
@@ -56,8 +59,26 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
#error "SLAVE LIB COMPILED INTO MASTER"
#endif
myDatif = new T_datif(this); // für die CAslave-Lib auskommentieren!
QSettings settings("/opt/app/ATBAPP/ATBQT.ini", QSettings::IniFormat);
m_powerctrl_cc = settings.value("AsyncPOS_CCPlugin/terminal_watch_file",
"/run/powerctrl_cc").toString();
m_fileSystemWatcher.reset(new QFileSystemWatcher());
m_powerctrl_modem = "/run/powerctrl_modem";
m_fileSystemWatcher->addPath(m_powerctrl_modem);
if (!m_fileSystemWatcher->addPath(m_powerctrl_cc)) {
qCritical() << "cannot add path for" << m_powerctrl_cc;
} else {
if (connect(m_fileSystemWatcher.get(), SIGNAL(fileChanged(QString const&)),
this, SLOT(onCCWakeGpioChanged(QString const&)))) {
qCritical() << "connected file watcher with" << m_powerctrl_cc;
}
}
myDatif = new T_datif(this); // für die CAslave-Lib auskommentieren!
#endif
#ifdef THIS_IS_CA_SLAVE
@@ -120,6 +141,62 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
connect(runProcess, SIGNAL(runProc_coinAttached()), this, SLOT(coinAttached()));
}
void hwapi::onCCWakeGpioChanged(QString const &fileName) {
qCritical() << __func__ << ":" << __LINE__ << fileName;
if (fileName == m_powerctrl_cc) {
QFile f(m_powerctrl_cc);
if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&f);
QString const &content = stream.readAll();
if (content.startsWith("0")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal off...";
credit_switchWake(false);
credit_switchPower(false);
} else
if (content.startsWith("1")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal on...";
credit_switchPower(true);
credit_switchWake(true);
} else
if (content.startsWith("2")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal off and on...";
credit_switchWake(false);
credit_switchPower(false);
QThread::sleep(1);
credit_switchPower(true);
credit_switchWake(true);
} else {
qCritical() << "switching cc-terminal watched file contained" << content;
QFile::resize(m_powerctrl_cc, 0); // empty file
}
}
}
else if (fileName == m_powerctrl_modem) {
QFile f(m_powerctrl_modem);
if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&f);
QString const &content = stream.readAll();
if (content.startsWith("0")) {
qCritical() << __func__ << ":" << __LINE__ << "switching modem off...";
mod_switchWake(false);
mod_switchPower(false);
} else
if (content.startsWith("1")) {
qCritical() << __func__ << ":" << __LINE__ << "switching modem on...";
mod_switchWake(true);
mod_switchPower(true);
}
}
}
else {
qCritical() << "ERROR watching the wrong file" << fileName << m_powerctrl_cc;
}
}
void hwapi::hwapi_slotPayProc(void)
{