Add first version which at least complies.
This commit is contained in:
parent
a21fa5fce9
commit
26c1f0143e
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.user
|
87
ATBAPP.h
Normal file
87
ATBAPP.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef ATBAPP_H
|
||||
#define ATBAPP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMetaType>
|
||||
|
||||
|
||||
enum class PROGRAM_MODE : quint8 {
|
||||
IDLE = 1,
|
||||
SELL_ENABLE = 2,
|
||||
SELL = 3,
|
||||
SERVICE = 4,
|
||||
OOO = 5
|
||||
};
|
||||
QDebug operator<<(QDebug debug, PROGRAM_MODE mode);
|
||||
|
||||
|
||||
|
||||
namespace CC_VARIANT {
|
||||
enum class TERMINAL : quint8 {
|
||||
NO_TERMINAL,
|
||||
INGENICO_CCTOPP,
|
||||
INGENICO_CHIP_AND_PIN,
|
||||
CCV,
|
||||
FEIG_CCTOPP,
|
||||
FEIG_CHIP_AND_PIN
|
||||
};
|
||||
}
|
||||
|
||||
namespace PAYMENT_VARIANTS {
|
||||
enum class CASH_VARIANT : quint8 {
|
||||
NO_CASH,
|
||||
CoinsOnly,
|
||||
CoinsAndNotes
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
enum class PAYMENT_POINTINTIME : quint8 {
|
||||
PAY_ON_ARRIVAL,
|
||||
PAY_ON_EXIT,
|
||||
IGNORE
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* APP_ACTION
|
||||
*
|
||||
*/
|
||||
|
||||
/* QVariant.toString() returns empty string for custom types, even if
|
||||
there is a .toString() method defined.
|
||||
From QT5.2 onwards there are new methods in QMetaType for registering
|
||||
comperator and converter methods:
|
||||
QMetaType::registerComparators()
|
||||
QMetaType::registerConverter()
|
||||
see: https://doc.qt.io/qt-5/qmetatype.html#registerComparators
|
||||
*/
|
||||
|
||||
|
||||
enum class APP_ACTION : int {
|
||||
DEFAULT_ACTION = 0x00,
|
||||
LICENSEPLATE_INPUT = 0x01, // License Plate Input
|
||||
PARKINGTIME_INPUT = 0x02, // Parking Time Input
|
||||
CARD_PAYMENT = 0x03, // CardPayment
|
||||
CHOOSE_PAYEMENT = 0x04, // Choose payment variant
|
||||
COIN_PAYMENT_PAYUP = 0x05,
|
||||
COIN_PAYMENT_PAYDOWN = 0x06,
|
||||
SEND_D0_CALC = 0x07,
|
||||
};
|
||||
Q_DECLARE_METATYPE(APP_ACTION)
|
||||
QDebug operator<<(QDebug debug, APP_ACTION action);
|
||||
|
||||
|
||||
enum class CP_STATE : quint8 {
|
||||
NO_STATE = 0x00,
|
||||
LICENSEPLATE_INPUT = 0x01, // with accessInformation only
|
||||
PARKINGTIME_INPUT = 0x02, // with accessInformation and parkingtime
|
||||
CARDINFO_INPUT = 0x03, // with accessInformation and cardInfo
|
||||
};
|
||||
Q_DECLARE_METATYPE(CP_STATE)
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // ATBAPP_H
|
862
ATBHMIconfig.cpp
Normal file
862
ATBHMIconfig.cpp
Normal file
@ -0,0 +1,862 @@
|
||||
#include "ATBHMIconfig.h"
|
||||
#include "atb_system.h"
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
|
||||
|
||||
|
||||
ATBHMIconfig::ATBHMIconfig(QObject *parent) : QObject(parent) {
|
||||
this->initEarly();
|
||||
this->initDefered();
|
||||
}
|
||||
|
||||
ATBHMIconfig::~ATBHMIconfig() {
|
||||
delete settings;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::initEarly() {
|
||||
QString settings_file = QCoreApplication::applicationDirPath() + "/ATBQT.ini";
|
||||
settings = new QSettings(settings_file, QSettings::IniFormat);
|
||||
settings->setIniCodec("UTF-8");
|
||||
configGroups = settings->childGroups();
|
||||
|
||||
// [COMMON]
|
||||
|
||||
settings->beginGroup("COMMON");
|
||||
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
ComPortName = settings->value("com_port_name", "/dev/ttyS0").toString();
|
||||
#else
|
||||
ComPortName = settings->value("com_port_name", "/dev/pts/20").toString();
|
||||
#endif
|
||||
ComBaudRate = settings->value("com_baud_rate", "115200").toInt();
|
||||
|
||||
if ((ComBaudRate != 115200) &&
|
||||
(ComBaudRate != 57600) &&
|
||||
(ComBaudRate != 9600)) { ComBaudRate = 115200; }
|
||||
|
||||
|
||||
lang1 = settings->value("lang1", "de_DE").toString();
|
||||
lang2 = settings->value("lang2", "en_US").toString();
|
||||
lang3 = settings->value("lang3", "fr_FR").toString();
|
||||
lang4 = settings->value("lang4", "ja_JP").toString();
|
||||
lang5 = settings->value("lang5", "nl-NL").toString();
|
||||
|
||||
useLanguage = static_cast<quint8>(settings->value("useLanguage", "255").toInt());
|
||||
|
||||
this->defaultLanguage = settings->value("defaultLanguage", "1").toInt();
|
||||
if ((this->defaultLanguage < 1) || (this->defaultLanguage > 5)) {
|
||||
this->defaultLanguage = 1;
|
||||
}
|
||||
|
||||
usePayment = static_cast<quint8>(settings->value("usePayment", "255").toInt());
|
||||
|
||||
useVehicle = static_cast<quint8>(settings->value("useVehicle", "255").toInt());
|
||||
|
||||
useProduct = static_cast<quint8>(settings->value("useProduct", "255").toInt());
|
||||
|
||||
|
||||
textfilename = settings->value("textfile", "HMI_Texte.xml").toString();
|
||||
#if defined (ARCH_DesktopLinux)
|
||||
QString filename = textfilename.split("/").last();
|
||||
textfilename = qApp->applicationDirPath() + "/text/" + filename;
|
||||
#endif
|
||||
|
||||
#if defined (ARCH_DesktopLinux)
|
||||
logfilename = QDir::homePath() + "/ATBAPP_VMC.log";
|
||||
#else
|
||||
logfilename = settings->value("logfile", "/var/log/atbqt.log").toString();
|
||||
#endif
|
||||
|
||||
oooServiceNumber = settings->value("ooo_serviceNumber", "").toString();
|
||||
|
||||
oooServiceEmail = settings->value("ooo_serviceEmail", "").toString();
|
||||
|
||||
oooAlternativeLocation = settings->value("ooo_alternativeLocation", "").toString();
|
||||
|
||||
alternativeLogoFilename = settings->value("alternativeLogoFile").toString();
|
||||
|
||||
this->features = 0;
|
||||
|
||||
// deprecated:
|
||||
qmPath = qApp->applicationDirPath() + "/translations";
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
/*
|
||||
* note: PSA configuration settings are not stored in ini-file
|
||||
*/
|
||||
cust_nr = "0";
|
||||
group_nr = "0";
|
||||
zone_nr = "0";
|
||||
machine_nr = "0";
|
||||
validPSAconfig = false;
|
||||
}
|
||||
|
||||
|
||||
void ATBHMIconfig::initDefered() {
|
||||
bool ok = false;
|
||||
|
||||
// [COMMON]
|
||||
|
||||
settings->beginGroup("COMMON");
|
||||
|
||||
SuspendMethode = settings->value("suspend_methode", "sysfs").toString();
|
||||
SuspendProgram = settings->value("suspend_program", "").toString();
|
||||
SuspendTime = settings->value("suspend_time", "10").toString();
|
||||
|
||||
if (settings->value("feature_Log", "on").toString() == "on" ||
|
||||
settings->value("feature_Log", "on").toString() == "yes" )
|
||||
{ this->setFeatureLog(); }
|
||||
else { this->unsetFeatureLog(); }
|
||||
|
||||
if (settings->value("feature_TouchFeedback", "on").toString() == "on" ||
|
||||
settings->value("feature_TouchFeedback", "on").toString() == "yes" )
|
||||
{ this->setFeatureTF(); }
|
||||
else { this->unsetFeatureTF(); }
|
||||
|
||||
if (settings->value("feature_DisplayControl", "off").toString() == "on" ||
|
||||
settings->value("feature_DisplayControl", "off").toString() == "yes" )
|
||||
{ this->setFeatureDC(); }
|
||||
else { this->unsetFeatureDC(); }
|
||||
|
||||
if (settings->value("feature_StartButton", "on").toString() == "on" ||
|
||||
settings->value("feature_StartButton", "on").toString() == "yes" )
|
||||
{ this->setFeatureStartButton(); }
|
||||
else { this->unsetFeatureStartButton(); }
|
||||
|
||||
if (settings->value("feature_selfOOO", "on").toString() == "on" ||
|
||||
settings->value("feature_selfOOO", "on").toString() == "yes" )
|
||||
{ this->setFeatureSelfOOO(); }
|
||||
else { this->unsetFeatureSelfOOO(); }
|
||||
|
||||
if (settings->value("feature_DBusDisplayControl", "on").toString() == "on" ||
|
||||
settings->value("feature_DBusDisplayControl", "on").toString() == "yes" )
|
||||
{ this->setFeatureDBusDisplayControl(); }
|
||||
else { this->unsetFeatureDBusDisplayControl(); }
|
||||
|
||||
if (settings->value("feature_DBusSuspendControl", "on").toString() == "on" ||
|
||||
settings->value("feature_DBusSuspendControl", "on").toString() == "yes" )
|
||||
{ this->setFeatureDBusSuspendControl(); }
|
||||
else { this->unsetFeatureDBusSuspendControl(); }
|
||||
|
||||
if (settings->value("feature_ShowParkingTime", "on").toString() == "on" ||
|
||||
settings->value("feature_ShowParkingTime", "on").toString() == "yes" )
|
||||
{ this->setFeatureShowParkingTime(); }
|
||||
else { this->unsetFeatureShowParkingTime(); }
|
||||
|
||||
|
||||
touch_feedback_gpio = settings->value("touch_feedback_gpio", "121").toString();
|
||||
|
||||
touch_feedback_on_value = settings->value("touch_feedback_on_value", "0").toString();
|
||||
touch_feedback_off_value = settings->value("touch_feedback_off_value", "1").toString();
|
||||
|
||||
QString ooo_mode = settings->value("ooo_mode", "useDisk").toString();
|
||||
if (ooo_mode == "useDisk")
|
||||
this->oooMode = OOO_MODE::USE_PARKDISK;
|
||||
else if (ooo_mode == "otherMachine")
|
||||
this->oooMode = OOO_MODE::USE_OTHER_MACHINE;
|
||||
else
|
||||
this->oooMode = OOO_MODE::DEFAULT;
|
||||
|
||||
characterSet = settings->value("CharacterSet", "ISO 8859-15").toByteArray();
|
||||
|
||||
qrCodeLink = settings->value("QRCodeLink", "").toString();
|
||||
|
||||
SellTimeoutTime = settings->value("sellTimeout_time", "60").toString();
|
||||
|
||||
this->privateReadInputDevices();
|
||||
|
||||
this->lpLocalExample = settings->value("LicencePlateExampleString", "HOAB123").toString();
|
||||
|
||||
|
||||
#if defined (USE_BARCODESCANNER)
|
||||
if (settings->value("useBarcode", "on").toString() == "on" ||
|
||||
settings->value("useBarcode", "on").toString() == "yes" )
|
||||
{ this->useBarcode = true; }
|
||||
else { this->useBarcode = false; }
|
||||
#endif // USE_BARCODESCANNER
|
||||
|
||||
#ifdef USE_RFIDREADER
|
||||
if (settings->value("useRFID", "on").toString() == "on" ||
|
||||
settings->value("useRFID", "on").toString() == "yes" )
|
||||
{ this->useRFID = true; }
|
||||
else { this->useRFID = false; }
|
||||
#endif
|
||||
|
||||
// DEBUG
|
||||
qDebug() << "ATBHMIconfig::initDefered() com_port_name = " << ComPortName;
|
||||
qDebug() << "ATBHMIconfig::initDefered() touch_feedback_gpio = " << touch_feedback_gpio;
|
||||
|
||||
// DEBUG: write settings to file:
|
||||
/*
|
||||
settings->setValue("com_port_name", this->ComPortName);
|
||||
settings->setValue("lang1", "de_DE");
|
||||
settings->setValue("lang2", "en_US");
|
||||
settings->setValue("lang3", "fr_FR");
|
||||
settings->setValue("lang4", "ja_JP");
|
||||
settings->setValue("textfile", "HMI_Texte.xml");
|
||||
settings->setValue("logfile", "/var/log/atbqt.log");
|
||||
settings->setValue("feature_Log", false);
|
||||
settings->setValue("feature_TouchFeedback", true);
|
||||
settings->setValue("feature_DisplayControl", true);
|
||||
settings->setValue("feature_SystemSuspend", true);
|
||||
settings->setValue("suspend_methode", "sysfs");
|
||||
settings->setValue("suspend_program", "");
|
||||
settings->setValue("suspend_time", 10);
|
||||
settings->setValue("touch_feedback_gpio", 121);
|
||||
settings->setValue("touch_feedback_on_value", 0);
|
||||
settings->setValue("touch_feedback_off_value", 1);
|
||||
*/
|
||||
|
||||
this->HelpButtonUsed = settings->value("showHelpButton", "0").toBool();
|
||||
this->InfoButtonUsed = settings->value("showInfoButton", "0").toBool();
|
||||
|
||||
this->ScreenChangeTimeoutTime = settings->value("screenChangeTimeoutTime", "10").toUInt();
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
// [PAYMENT]
|
||||
|
||||
settings->beginGroup("PAYMENT");
|
||||
|
||||
QString cashVariantString = settings->value("cashVariant", "CoinsOnly").toString();
|
||||
if (cashVariantString == "CoinsOnly") {
|
||||
this->cashVariant = PAYMENT_VARIANTS::CASH_VARIANT::CoinsOnly;
|
||||
}
|
||||
else
|
||||
if (cashVariantString == "CoinsAndNotes") {
|
||||
this->cashVariant = PAYMENT_VARIANTS::CASH_VARIANT::CoinsAndNotes;
|
||||
}
|
||||
else {
|
||||
// Default
|
||||
this->cashVariant = PAYMENT_VARIANTS::CASH_VARIANT::CoinsOnly;
|
||||
}
|
||||
|
||||
this->currencySymbol = settings->value("currencySymbol", "€").toString();
|
||||
|
||||
|
||||
QString paymentPointInTimeString = settings->value("paymentPointInTime", "poe").toString();
|
||||
if (paymentPointInTimeString == "poe") {
|
||||
this->paymentPointInTime = PAYMENT_POINTINTIME::PAY_ON_EXIT;
|
||||
}
|
||||
else
|
||||
if (paymentPointInTimeString == "poa") {
|
||||
this->paymentPointInTime = PAYMENT_POINTINTIME::PAY_ON_ARRIVAL;
|
||||
}
|
||||
else
|
||||
if (paymentPointInTimeString == "ign") {
|
||||
this->paymentPointInTime = PAYMENT_POINTINTIME::IGNORE;
|
||||
}
|
||||
else {
|
||||
// Default
|
||||
this->paymentPointInTime = PAYMENT_POINTINTIME::PAY_ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
if (settings->value("useHonestPayment", "on").toString() == "on" ||
|
||||
settings->value("useHonestPayment", "on").toString() == "yes" )
|
||||
{ this->honestPayment = true; }
|
||||
else { this->honestPayment = false; }
|
||||
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
// [CUSTOMER]
|
||||
|
||||
settings->beginGroup("CUSTOMER");
|
||||
|
||||
this->DiscountUsed = settings->value("DiscountUsed", "1").toBool();
|
||||
this->QRCodeReceiptUsed = settings->value("QRCodeReceiptUsed", "1").toBool();
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
#ifdef USE_EXTERNAL_TICKETMANAGER
|
||||
// [BARCODE_VERIFICATION]
|
||||
|
||||
settings->beginGroup("BARCODE_VERIFICATION");
|
||||
|
||||
this->endOfSellingTime = settings->value("EndOfSellingTime", "06:00").toString();
|
||||
this->blockingTimeMin = settings->value("BlockingTime_Min", "15").toInt(&ok);
|
||||
if (!ok) this->blockingTimeMin = 15;
|
||||
|
||||
settings->endGroup();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_ISMAS
|
||||
// [ISMAS]
|
||||
|
||||
settings->beginGroup("ISMAS");
|
||||
|
||||
this->ismasHost = settings->value("ISMAS_HOST", "87.139.50.222").toString();
|
||||
this->ismasPort = settings->value("ISMAS_PORT", "10000").toInt(&ok);
|
||||
this->ismasID = settings->value("ISMAS_ID", "").toString();
|
||||
|
||||
if (settings->value("ISMAS_DEBUG", "on").toString() == "on" ||
|
||||
settings->value("ISMAS_DEBUG", "on").toString() == "yes")
|
||||
{ this->ismasDebug = true; }
|
||||
else { this->ismasDebug = false; }
|
||||
|
||||
if (settings->value("ISMAS_CheckEntries", "on").toString() == "on" ||
|
||||
settings->value("ISMAS_CheckEntries", "on").toString() == "yes")
|
||||
{ this->ismasCheckEntries = true; }
|
||||
else { this->ismasCheckEntries = false; }
|
||||
|
||||
this->ismasConnectionTimeout = settings->value("ISMAS_ConnectionTimeout", "2").toInt(&ok);
|
||||
if (!ok) this->ismasConnectionTimeout = 2;
|
||||
|
||||
if (settings->value("usePinGenerator", "off").toString() == "on" ||
|
||||
settings->value("usePinGenerator", "off").toString() == "yes" )
|
||||
{ this->usePINgenerator = true; }
|
||||
else { this->usePINgenerator = false; }
|
||||
|
||||
settings->endGroup();
|
||||
#endif
|
||||
|
||||
// [ERRORCODE_MAPPING]
|
||||
|
||||
if (settings->childGroups().contains("ERRORCODE_MAPPING")) {
|
||||
settings->beginGroup("ERRORCODE_MAPPING");
|
||||
|
||||
QStringList ErrorCodes = settings->childKeys();
|
||||
|
||||
for (int i = 0; i < ErrorCodes.size(); ++i) {
|
||||
errorTextHash.insert(ErrorCodes.at(i), settings->value(ErrorCodes.at(i),"").toString());
|
||||
}
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
|
||||
qDebug() << ok;
|
||||
}
|
||||
|
||||
|
||||
QSettings * ATBHMIconfig::getSettingsPtr() { return this->settings; }
|
||||
|
||||
const QSettings & ATBHMIconfig::getSettings() { return *(this->settings); }
|
||||
|
||||
QString ATBHMIconfig::getComPortName() { return this->ComPortName; }
|
||||
|
||||
QString ATBHMIconfig::getSuspendMethode() { return this->SuspendMethode; }
|
||||
|
||||
QString ATBHMIconfig::getSuspendProgram() { return this->SuspendProgram; }
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* get suspend time (-> time, after system goes to suspend) in seconds
|
||||
*/
|
||||
QString ATBHMIconfig::getSuspendTime() { return this->SuspendTime; }
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* get sell timout time (-> time, after system switched back to mode idle, if we do not have
|
||||
* any user inputs or vmc messages during sell mode) in seconds
|
||||
*/
|
||||
QString ATBHMIconfig::getSellTimeoutTime() { return this->SellTimeoutTime; }
|
||||
|
||||
quint32 ATBHMIconfig::getHMIScreenChangeTimeoutTime() { return this->ScreenChangeTimeoutTime; }
|
||||
|
||||
QString ATBHMIconfig::getQmPath() { return this->qmPath; }
|
||||
|
||||
bool ATBHMIconfig::hasFeatureTF() { return ((this->features & this->featureMaskTF) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureLog() { return ((this->features & this->featureMaskLog) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureDC() { return ((this->features & this->featureMaskDC) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureStartButton() { return ((this->features & this->featureMaskStartButton) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureSelfOOO() { return ((this->features & this->featureMaskSelfOOO) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureDBusDisplayControl() { return ((this->features & this->featureMaskDBusDisplayControl) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureDBusSuspendControl() { return ((this->features & this->featureMaskDBusSuspendControl) != 0); }
|
||||
bool ATBHMIconfig::hasFeatureShowParkingTime() { return ((this->features & this->featureMaskShowParkingTime) != 0); }
|
||||
|
||||
void ATBHMIconfig::setFeatureTF() { this->features |= this->featureMaskTF; }
|
||||
void ATBHMIconfig::unsetFeatureTF() { this->features &= ~(this->featureMaskTF); }
|
||||
void ATBHMIconfig::setFeatureLog() { this->features |= this->featureMaskLog; }
|
||||
void ATBHMIconfig::unsetFeatureLog() { this->features &= ~(this->featureMaskLog); }
|
||||
void ATBHMIconfig::setFeatureStartButton() { this->features |= this->featureMaskStartButton; }
|
||||
void ATBHMIconfig::unsetFeatureStartButton() { this->features &= ~(this->featureMaskStartButton); }
|
||||
void ATBHMIconfig::setFeatureSelfOOO() { this->features |= this->featureMaskSelfOOO; }
|
||||
void ATBHMIconfig::unsetFeatureSelfOOO() { this->features &= ~(this->featureMaskSelfOOO); }
|
||||
|
||||
|
||||
void ATBHMIconfig::setFeatureDC()
|
||||
{
|
||||
// this features are mutually exclusive
|
||||
if (this->hasFeatureDBusDisplayControl()) {
|
||||
this->unsetFeatureDBusDisplayControl();
|
||||
}
|
||||
this->features |= this->featureMaskDC;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::unsetFeatureDC() { this->features &= ~(this->featureMaskDC); }
|
||||
|
||||
|
||||
void ATBHMIconfig::setFeatureDBusDisplayControl()
|
||||
{
|
||||
// this features are mutually exclusive
|
||||
if (this->hasFeatureDC()) {
|
||||
this->unsetFeatureDC();
|
||||
}
|
||||
this->features |= this->featureMaskDBusDisplayControl;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::setFeatureDBusSuspendControl()
|
||||
{
|
||||
this->features |= this->featureMaskDBusSuspendControl;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::unsetFeatureDBusDisplayControl() { this->features &= ~(this->featureMaskDBusDisplayControl); }
|
||||
void ATBHMIconfig::unsetFeatureDBusSuspendControl() { this->features &= ~(this->featureMaskDBusSuspendControl); }
|
||||
|
||||
void ATBHMIconfig::setFeatureShowParkingTime() { this->features |= this->featureMaskShowParkingTime; }
|
||||
void ATBHMIconfig::unsetFeatureShowParkingTime() { this->features &= ~(this->featureMaskShowParkingTime); }
|
||||
|
||||
|
||||
QString ATBHMIconfig::getTouchFeedbackGPIO() { return this->touch_feedback_gpio; }
|
||||
QString ATBHMIconfig::getTouchFeedbackOnValue() { return this->touch_feedback_on_value; }
|
||||
QString ATBHMIconfig::getTouchFeedbackOffValue() { return this->touch_feedback_off_value; }
|
||||
|
||||
QString ATBHMIconfig::getTextfileName() { return this->textfilename; }
|
||||
|
||||
QString ATBHMIconfig::getAlternativeLogoFilename() { return this->alternativeLogoFilename; }
|
||||
|
||||
#ifdef USE_BARCODESCANNER
|
||||
bool ATBHMIconfig::getUseBarcodeScanner() { return this->useBarcode; }
|
||||
QString & ATBHMIconfig::getBarcodeScannerInputDevice() { return this->barcodeScannerInputDeviceName; }
|
||||
#endif
|
||||
|
||||
#ifdef USE_RFIDREADER
|
||||
bool ATBHMIconfig::getUseRFIDReader() { return this->useRFID; }
|
||||
QString & ATBHMIconfig::getRFIDReaderInputDevice() { return this->rfidReaderInputDeviceName; }
|
||||
#endif
|
||||
|
||||
PAYMENT_VARIANTS::CASH_VARIANT ATBHMIconfig::getCashVariant() { return this->cashVariant; }
|
||||
|
||||
bool ATBHMIconfig::discountIsUsed() { return this->DiscountUsed; }
|
||||
bool ATBHMIconfig::qrCodeReceiptIsUsed() { return this->QRCodeReceiptUsed; }
|
||||
|
||||
#ifdef USE_EXTERNAL_TICKETMANAGER
|
||||
/**********************************************************************
|
||||
* for barcode verification:
|
||||
*
|
||||
* EndOfSellingTime: time, when all daily data (e.g. blocking list) is reset
|
||||
* BlockingTime: time, in minutes, how long a verified ticket is blocked for reentry
|
||||
*/
|
||||
QString ATBHMIconfig::getEndOfSellingTime() { return this->endOfSellingTime; }
|
||||
int ATBHMIconfig::getBlockingTime() { return this->blockingTimeMin; }
|
||||
#endif
|
||||
|
||||
QString ATBHMIconfig::getLang(int lang)
|
||||
{
|
||||
switch (lang) {
|
||||
case 1: return this->lang1;
|
||||
break;
|
||||
case 2: return this->lang2;
|
||||
break;
|
||||
case 3: return this->lang3;
|
||||
break;
|
||||
case 4: return this->lang4;
|
||||
break;
|
||||
case 5: return this->lang5;
|
||||
break;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ordered list of configured languages.
|
||||
* { <lang1>, <lang2>, ... , <langN> }
|
||||
* This languages should be available in text file.
|
||||
*/
|
||||
QStringList ATBHMIconfig::getConfiguredLanguages()
|
||||
{
|
||||
QStringList langs;
|
||||
langs << lang1 << lang2 << lang3 << lang4 << lang5;
|
||||
return langs;
|
||||
}
|
||||
|
||||
|
||||
QString ATBHMIconfig::getCountry(int country)
|
||||
{
|
||||
switch (country) {
|
||||
case 1: return this->country1;
|
||||
break;
|
||||
case 2: return this->country2;
|
||||
break;
|
||||
case 3: return this->country3;
|
||||
break;
|
||||
case 4: return this->country4;
|
||||
break;
|
||||
case 5: return this->country5;
|
||||
break;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool ATBHMIconfig::isLanguageUsed(int lang)
|
||||
{
|
||||
switch (lang) {
|
||||
case 1: return (this->useLanguage & 0x80) ? (true) : (false);
|
||||
break;
|
||||
case 2: return (this->useLanguage & 0x40) ? (true) : (false);
|
||||
break;
|
||||
case 3: return (this->useLanguage & 0x20) ? (true) : (false);
|
||||
break;
|
||||
case 4: return (this->useLanguage & 0x10) ? (true) : (false);
|
||||
break;
|
||||
case 5: return (this->useLanguage & 0x08) ? (true) : (false);
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ATBHMIconfig::isInfoButtonUsed() { return this->InfoButtonUsed; }
|
||||
bool ATBHMIconfig::isHelpButtonUsed() { return this->HelpButtonUsed; }
|
||||
|
||||
|
||||
bool ATBHMIconfig::isPaymentUsed(int payment)
|
||||
{
|
||||
switch (payment) {
|
||||
case 1: return (this->usePayment & 0x80) ? (true) : (false);
|
||||
break;
|
||||
case 2: return (this->usePayment & 0x40) ? (true) : (false);
|
||||
break;
|
||||
case 3: return (this->usePayment & 0x20) ? (true) : (false);
|
||||
break;
|
||||
case 4: return (this->usePayment & 0x10) ? (true) : (false);
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ATBHMIconfig::isVehicleUsed(int vehicle)
|
||||
{
|
||||
switch (vehicle) {
|
||||
case 1: return (this->useVehicle & 0x80) ? (true) : (false);
|
||||
break;
|
||||
case 2: return (this->useVehicle & 0x40) ? (true) : (false);
|
||||
break;
|
||||
case 3: return (this->useVehicle & 0x20) ? (true) : (false);
|
||||
break;
|
||||
case 4: return (this->useVehicle & 0x10) ? (true) : (false);
|
||||
break;
|
||||
case 5: return (this->useVehicle & 0x08) ? (true) : (false);
|
||||
break;
|
||||
case 6: return (this->useVehicle & 0x04) ? (true) : (false);
|
||||
break;
|
||||
case 7: return (this->useVehicle & 0x02) ? (true) : (false);
|
||||
break;
|
||||
case 8: return (this->useVehicle & 0x01) ? (true) : (false);
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ATBHMIconfig::isProductUsed(int product)
|
||||
{
|
||||
switch (product) {
|
||||
case 1: return (this->useProduct & 0x80) ? (true) : (false);
|
||||
break;
|
||||
case 2: return (this->useProduct & 0x40) ? (true) : (false);
|
||||
break;
|
||||
case 3: return (this->useProduct & 0x20) ? (true) : (false);
|
||||
break;
|
||||
case 4: return (this->useProduct & 0x10) ? (true) : (false);
|
||||
break;
|
||||
case 5: return (this->useProduct & 0x08) ? (true) : (false);
|
||||
break;
|
||||
case 6: return (this->useProduct & 0x04) ? (true) : (false);
|
||||
break;
|
||||
case 7: return (this->useProduct & 0x02) ? (true) : (false);
|
||||
break;
|
||||
case 8: return (this->useProduct & 0x01) ? (true) : (false);
|
||||
break;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString ATBHMIconfig::getLogFileName()
|
||||
{
|
||||
return this->logfilename;
|
||||
}
|
||||
|
||||
int ATBHMIconfig::getDefaultLanguage()
|
||||
{
|
||||
return this->defaultLanguage;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::setDefaultLanguage(quint8 lang)
|
||||
{
|
||||
this->defaultLanguage = lang;
|
||||
}
|
||||
|
||||
|
||||
int ATBHMIconfig::getComBaudRate()
|
||||
{
|
||||
return this->ComBaudRate;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Funktions for storing some machine specific configuration data in filesystem.
|
||||
*
|
||||
* Note: this functions must reduce write operations to flash memory.
|
||||
* Therefore, first the data values are read from memory and compared to the new ones.
|
||||
* Only changed values should be written.
|
||||
* Additionally, open files, read their values and compare this values is time consuming.
|
||||
* So we store this values also in our config-object and do only a comparisson if values
|
||||
* have changed.
|
||||
*
|
||||
*
|
||||
*/
|
||||
QString & ATBHMIconfig::getCustNr()
|
||||
{
|
||||
if (!this->validPSAconfig) { this->readPSAConfig(); }
|
||||
return this->cust_nr;
|
||||
}
|
||||
|
||||
QString & ATBHMIconfig::getGroupNr()
|
||||
{
|
||||
if (!this->validPSAconfig) { this->readPSAConfig(); }
|
||||
return this->group_nr;
|
||||
}
|
||||
|
||||
QString & ATBHMIconfig::getZoneNr()
|
||||
{
|
||||
if (!this->validPSAconfig) { this->readPSAConfig(); }
|
||||
return this->zone_nr;
|
||||
}
|
||||
|
||||
QString & ATBHMIconfig::getMachineNr()
|
||||
{
|
||||
if (!this->validPSAconfig) { this->readPSAConfig(); }
|
||||
return this->machine_nr;
|
||||
}
|
||||
|
||||
quint8 ATBHMIconfig::readPSAConfig()
|
||||
{
|
||||
this->cust_nr = ATB_system::readPSAConfigString("/etc/cust_nr");
|
||||
this->group_nr = ATB_system::readPSAConfigString("/etc/group_nr");
|
||||
this->zone_nr = ATB_system::readPSAConfigString("/etc/zone_nr");
|
||||
this->machine_nr = ATB_system::readPSAConfigString("/etc/machine_nr");
|
||||
this->validPSAconfig = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ATBHMIconfig::setCustNr(const QString& cust_nr)
|
||||
{
|
||||
if (! validPSAconfig) { this->readPSAConfig(); }
|
||||
|
||||
// compare to cached value:
|
||||
|
||||
if (cust_nr != this->cust_nr) { // Customer number has changed
|
||||
ATB_system::setPSAConfigString("/etc/cust_nr", cust_nr);
|
||||
this->cust_nr = cust_nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ATBHMIconfig::setGroupNr(const QString& group_nr)
|
||||
{
|
||||
if (! validPSAconfig) { this->readPSAConfig(); }
|
||||
|
||||
// compare to cached value:
|
||||
|
||||
if (group_nr != this->group_nr) {
|
||||
ATB_system::setPSAConfigString("/etc/group_nr", group_nr);
|
||||
this->group_nr = group_nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ATBHMIconfig::setZoneNr(const QString& zone_nr)
|
||||
{
|
||||
if (! validPSAconfig) { this->readPSAConfig(); }
|
||||
|
||||
// compare to cached value:
|
||||
|
||||
if (zone_nr != this->zone_nr) {
|
||||
ATB_system::setPSAConfigString("/etc/zone_nr", zone_nr);
|
||||
this->zone_nr = zone_nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ATBHMIconfig::setMachineNr(const QString &machine_nr)
|
||||
{
|
||||
if (! validPSAconfig) { this->readPSAConfig(); }
|
||||
|
||||
// compare to cached value:
|
||||
|
||||
if (machine_nr != this->machine_nr) {
|
||||
ATB_system::setPSAConfigString("/etc/machine_nr", machine_nr);
|
||||
this->machine_nr = machine_nr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OOO_MODE ATBHMIconfig::getOOOMode()
|
||||
{
|
||||
return this->oooMode;
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getOOOModeString()
|
||||
{
|
||||
switch (this->oooMode) {
|
||||
case OOO_MODE::USE_OTHER_MACHINE:
|
||||
return QString("otherMachine");
|
||||
break;
|
||||
case OOO_MODE::USE_PARKDISK:
|
||||
return QString("useDisk");
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getOOOServiceNumber()
|
||||
{
|
||||
return this->oooServiceNumber;
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getOOOServiceEmail()
|
||||
{
|
||||
return this->oooServiceEmail;
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getOOOAlternativeLocation()
|
||||
{
|
||||
return this->oooAlternativeLocation;
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getLicensePlateExampleString()
|
||||
{
|
||||
return this->lpLocalExample;
|
||||
}
|
||||
|
||||
QString ATBHMIconfig::getQrCodeLink()
|
||||
{
|
||||
return this->qrCodeLink;
|
||||
}
|
||||
|
||||
const QByteArray & ATBHMIconfig::getDefaultCharacterSet() const
|
||||
{
|
||||
return this->characterSet;
|
||||
}
|
||||
|
||||
|
||||
const QString & ATBHMIconfig::getPaymentCurrencySymbol()
|
||||
{
|
||||
return this->currencySymbol;
|
||||
}
|
||||
|
||||
PAYMENT_POINTINTIME ATBHMIconfig::getPaymentPointInTime()
|
||||
{
|
||||
return this->paymentPointInTime;
|
||||
}
|
||||
|
||||
bool ATBHMIconfig::useHonestPayment()
|
||||
{
|
||||
return this->honestPayment;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* public slot to re-read config
|
||||
*
|
||||
* This slot could be called e.g. on a mode switch from 'service' to 'sell' or vv.
|
||||
*/
|
||||
void ATBHMIconfig::reReadSettings()
|
||||
{
|
||||
this->privateReadInputDevices();
|
||||
}
|
||||
|
||||
/* private common function to set/read input device names.
|
||||
*/
|
||||
void ATBHMIconfig::privateReadInputDevices()
|
||||
{
|
||||
#if defined (USE_BARCODESCANNER)
|
||||
barcodeScannerInputDeviceName = ATB_system::getEventDeviceName(ATB_system::EVENT_DEVICE_BARCODEREADER);
|
||||
#endif // USE_BARCODESCANNER
|
||||
|
||||
#if defined (USE_RFIDREADER)
|
||||
rfidReaderInputDeviceName = ATB_system::getEventDeviceName(ATB_system::EVENT_DEVICE_RFIDREADER);
|
||||
#endif // USE_RFIDREADER
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ISMAS
|
||||
*/
|
||||
#ifdef USE_ISMAS
|
||||
QString ATBHMIconfig::getISMASHost() { return this->ismasHost; }
|
||||
quint16 ATBHMIconfig::getISMASPort() { return this->ismasPort; }
|
||||
bool ATBHMIconfig::isIsmasDebug() { return this->ismasDebug; }
|
||||
bool ATBHMIconfig::IsmasCheckEntries() { return this->ismasCheckEntries; }
|
||||
quint16 ATBHMIconfig::getIsmasConnectionTimeout() { return this->ismasConnectionTimeout; }
|
||||
bool ATBHMIconfig::UsePINgenerator() { return this->usePINgenerator; }
|
||||
QString ATBHMIconfig::getISMASId()
|
||||
{
|
||||
// if no ismasID is defined, we use customer Number (-> "ATB device Id" in Multipass)
|
||||
if (this->ismasID == "") {
|
||||
return this->getCustNr();
|
||||
}
|
||||
return this->ismasID;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* public methods for ErrorCode
|
||||
*/
|
||||
QString ATBHMIconfig::getErrorText(const QString & errorCode)
|
||||
{
|
||||
return errorTextHash.value(errorCode);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* get tools name/path
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* check availability of network diag tool
|
||||
*
|
||||
* possible install path for networkDiag:
|
||||
* 1) /usr/bin/atb_networkDiag
|
||||
* 2) /opt/app/tools/networkDiag
|
||||
* 3) /opt/app/atb_networkDiag/networkDiag
|
||||
*
|
||||
* Check, if file exists and if it is executable,
|
||||
* Return path/name for binary.
|
||||
*/
|
||||
QString & ATBHMIconfig::getNetworkDiagTool()
|
||||
{
|
||||
// search list for config file:
|
||||
QStringList binFileList;
|
||||
|
||||
// check, if file exists and if it is executable
|
||||
#if defined (ARCH_PTU4)
|
||||
binFileList << "/usr/bin/atbNetworkDiag"
|
||||
<< "/opt/app/tools/networkDiag"
|
||||
<< "/opt/app/atbNetworkDiag/networkDiag";
|
||||
#else
|
||||
binFileList << QDir::homePath().append("/atbNetworkDiag");
|
||||
#endif
|
||||
|
||||
// using C++11 range based loop: -> take first file, which is readable
|
||||
for (const auto& filename : binFileList) {
|
||||
if (QFileInfo(filename).isExecutable()) {
|
||||
this->networkDiagToolName = filename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this->networkDiagToolName;
|
||||
}
|
338
ATBHMIconfig.h
Normal file
338
ATBHMIconfig.h
Normal file
@ -0,0 +1,338 @@
|
||||
#ifndef ATBHMICONFIG_H
|
||||
#define ATBHMICONFIG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <ATBAPP.h>
|
||||
#include "version.h"
|
||||
|
||||
|
||||
/***************************************
|
||||
* Sample configuration:
|
||||
*
|
||||
* [General]
|
||||
* com_port_name=/dev/pts/16
|
||||
* machine_nr=99
|
||||
*
|
||||
* suspend_methode=sysfs
|
||||
* suspend_program=
|
||||
* suspend_time=10
|
||||
*
|
||||
* touch_feedback=on
|
||||
* touch_feedback_gpio=115 // 115 = beep; 121 = vibration motor
|
||||
* touch_feedback_on_value=0 // 0 (buzzer) 1 (vibration)
|
||||
* touch_feedback_off_value=1 // 1 (buzzer) 0 (vibration)
|
||||
*
|
||||
* log=on // loggin is on
|
||||
*
|
||||
* lang1=de_DE
|
||||
* lang2=en_US
|
||||
* lang3=fr_FR
|
||||
* lang4=ja_JP
|
||||
*
|
||||
* textfile=HMI_Texte.xml
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
enum class OOO_MODE : quint8;
|
||||
|
||||
|
||||
class ATBHMIconfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QString ComPortName;
|
||||
|
||||
QString SuspendMethode;
|
||||
QString SuspendProgram;
|
||||
QString SuspendTime;
|
||||
|
||||
QString SellTimeoutTime;
|
||||
|
||||
QString qmPath;
|
||||
|
||||
QString touch_feedback_gpio;
|
||||
QString touch_feedback_on_value;
|
||||
QString touch_feedback_off_value;
|
||||
|
||||
|
||||
QString lang1;
|
||||
QString lang2;
|
||||
QString lang3;
|
||||
QString lang4;
|
||||
QString lang5;
|
||||
|
||||
quint8 useLanguage;
|
||||
quint8 useVehicle;
|
||||
quint8 useProduct;
|
||||
quint8 usePayment;
|
||||
|
||||
QString country1;
|
||||
QString country2;
|
||||
QString country3;
|
||||
QString country4;
|
||||
QString country5;
|
||||
|
||||
QSettings *settings;
|
||||
|
||||
quint16 features;
|
||||
static const quint16 featureMaskTF = 0x0001;
|
||||
static const quint16 featureMaskLog = 0x0002;
|
||||
static const quint16 featureMaskDC = 0x0004; // manuell display control, (in future deprecated)
|
||||
static const quint16 featureMaskSusp = 0x0008; // manuell suspend control, (in future deprecated)
|
||||
static const quint16 featureMaskStartButton = 0x0010;
|
||||
static const quint16 featureMaskSelfOOO = 0x0020;
|
||||
static const quint16 featureMaskDBusDisplayControl = 0x0040;
|
||||
static const quint16 featureMaskDBusSuspendControl = 0x0080;
|
||||
static const quint16 featureMaskShowParkingTime = 0x0100;
|
||||
|
||||
|
||||
|
||||
QString logfilename;
|
||||
|
||||
QString textfilename;
|
||||
|
||||
QString alternativeLogoFilename;
|
||||
|
||||
QString oooServiceNumber;
|
||||
|
||||
QString oooServiceEmail;
|
||||
|
||||
QString oooAlternativeLocation;
|
||||
|
||||
QString qrCodeLink;
|
||||
|
||||
QString lpLocalExample;
|
||||
|
||||
QString currencySymbol;
|
||||
|
||||
#ifdef USE_BARCODESCANNER
|
||||
bool useBarcode;
|
||||
QString barcodeScannerInputDeviceName;
|
||||
#endif
|
||||
|
||||
#ifdef USE_RFIDREADER
|
||||
bool useRFID;
|
||||
QString rfidReaderInputDeviceName;
|
||||
#endif
|
||||
|
||||
#ifdef USE_EXTERNAL_TICKETMANAGER
|
||||
// for ticket management
|
||||
QString endOfSellingTime;
|
||||
int blockingTimeMin;
|
||||
#endif
|
||||
|
||||
quint8 defaultLanguage;
|
||||
|
||||
|
||||
bool HelpButtonUsed;
|
||||
bool InfoButtonUsed;
|
||||
bool DiscountUsed;
|
||||
bool QRCodeReceiptUsed;
|
||||
|
||||
int ComBaudRate;
|
||||
|
||||
QString cust_nr;
|
||||
QString group_nr;
|
||||
QString zone_nr;
|
||||
QString machine_nr;
|
||||
bool validPSAconfig;
|
||||
|
||||
QByteArray characterSet;
|
||||
|
||||
#ifdef USE_ISMAS
|
||||
QString ismasHost;
|
||||
quint16 ismasPort;
|
||||
QString ismasID;
|
||||
bool ismasDebug;
|
||||
bool ismasCheckEntries;
|
||||
quint16 ismasConnectionTimeout;
|
||||
bool usePINgenerator;
|
||||
#endif
|
||||
|
||||
quint32 ScreenChangeTimeoutTime;
|
||||
|
||||
PAYMENT_VARIANTS::CASH_VARIANT cashVariant;
|
||||
|
||||
// ErrorCode-mapping
|
||||
QHash<QString,QString> errorTextHash;
|
||||
|
||||
public:
|
||||
explicit ATBHMIconfig(QObject *parent = nullptr);
|
||||
~ATBHMIconfig();
|
||||
|
||||
QSettings *getSettingsPtr();
|
||||
const QSettings & getSettings();
|
||||
|
||||
void initEarly();
|
||||
void initDefered();
|
||||
|
||||
QString getComPortName();
|
||||
|
||||
QString getSuspendMethode();
|
||||
QString getSuspendProgram();
|
||||
QString getSuspendTime();
|
||||
|
||||
QString getSellTimeoutTime();
|
||||
|
||||
quint32 getHMIScreenChangeTimeoutTime();
|
||||
|
||||
QString getQmPath();
|
||||
|
||||
QString getLang(int lang);
|
||||
QString getCountry(int country);
|
||||
bool isLanguageUsed(int lang);
|
||||
|
||||
bool isInfoButtonUsed();
|
||||
bool isHelpButtonUsed();
|
||||
|
||||
bool isPaymentUsed(int payment);
|
||||
bool isVehicleUsed(int vehicle);
|
||||
bool isProductUsed(int product);
|
||||
bool isProcductUsed(int product);
|
||||
|
||||
QString getTouchFeedbackGPIO();
|
||||
QString getTouchFeedbackOnValue();
|
||||
QString getTouchFeedbackOffValue();
|
||||
|
||||
bool hasFeatureTF(); // touch feedback
|
||||
bool hasFeatureLog(); // log serial communication
|
||||
bool hasFeatureDC(); // display control
|
||||
bool hasFeatureStartButton(); // StartButton
|
||||
bool hasFeatureSelfOOO(); // self ooo capability
|
||||
bool hasFeatureDBusDisplayControl();
|
||||
bool hasFeatureDBusSuspendControl();
|
||||
bool hasFeatureShowParkingTime(); // show parking time in addition to parking end time
|
||||
|
||||
|
||||
QString getTextfileName();
|
||||
QString getAlternativeLogoFilename();
|
||||
|
||||
const QByteArray & getDefaultCharacterSet() const;
|
||||
|
||||
QString getOOOServiceNumber();
|
||||
QString getOOOServiceEmail();
|
||||
QString getOOOAlternativeLocation();
|
||||
QString getLicensePlateExampleString();
|
||||
QString getQrCodeLink();
|
||||
|
||||
const QString & getPaymentCurrencySymbol();
|
||||
|
||||
#ifdef USE_BARCODESCANNER
|
||||
bool getUseBarcodeScanner();
|
||||
QString & getBarcodeScannerInputDevice();
|
||||
#endif
|
||||
|
||||
#ifdef USE_RFIDREADER
|
||||
bool getUseRFIDReader();
|
||||
QString & getRFIDReaderInputDevice();
|
||||
#endif
|
||||
|
||||
#ifdef USE_EXTERNAL_TICKETMANAGER
|
||||
QString getEndOfSellingTime();
|
||||
int getBlockingTime();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ISMAS
|
||||
QString getISMASHost();
|
||||
quint16 getISMASPort();
|
||||
QString getISMASId();
|
||||
bool isIsmasDebug();
|
||||
bool IsmasCheckEntries();
|
||||
bool UsePINgenerator();
|
||||
quint16 getIsmasConnectionTimeout();
|
||||
#endif
|
||||
|
||||
void setFeatureTF();
|
||||
void unsetFeatureTF();
|
||||
|
||||
void setFeatureLog();
|
||||
void unsetFeatureLog();
|
||||
|
||||
void setFeatureDC();
|
||||
void unsetFeatureDC();
|
||||
|
||||
void setFeatureStartButton();
|
||||
void unsetFeatureStartButton();
|
||||
|
||||
void setFeatureSelfOOO();
|
||||
void unsetFeatureSelfOOO();
|
||||
|
||||
void setFeatureDBusDisplayControl();
|
||||
void unsetFeatureDBusDisplayControl();
|
||||
|
||||
void setFeatureDBusSuspendControl();
|
||||
void unsetFeatureDBusSuspendControl();
|
||||
|
||||
void setFeatureShowParkingTime();
|
||||
void unsetFeatureShowParkingTime();
|
||||
|
||||
QString getLogFileName();
|
||||
|
||||
int getDefaultLanguage();
|
||||
QStringList getConfiguredLanguages();
|
||||
|
||||
int getComBaudRate();
|
||||
|
||||
QString getErrorText(const QString & errorCode);
|
||||
|
||||
// machine configuration
|
||||
QString & getCustNr();
|
||||
QString & getGroupNr();
|
||||
QString & getZoneNr();
|
||||
QString & getMachineNr();
|
||||
quint8 readPSAConfig();
|
||||
|
||||
PAYMENT_VARIANTS::CASH_VARIANT getCashVariant();
|
||||
|
||||
bool discountIsUsed();
|
||||
bool qrCodeReceiptIsUsed();
|
||||
|
||||
// service programs
|
||||
QString & getNetworkDiagTool();
|
||||
//QString & getPTUConfig();
|
||||
//QString & getPTUUpdate();
|
||||
|
||||
OOO_MODE getOOOMode();
|
||||
|
||||
QString getOOOModeString();
|
||||
|
||||
PAYMENT_POINTINTIME getPaymentPointInTime();
|
||||
bool useHonestPayment();
|
||||
|
||||
QStringList configGroups;
|
||||
|
||||
private:
|
||||
OOO_MODE oooMode;
|
||||
|
||||
PAYMENT_POINTINTIME paymentPointInTime;
|
||||
bool honestPayment;
|
||||
|
||||
void privateReadInputDevices();
|
||||
|
||||
QString networkDiagToolName;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setDefaultLanguage(quint8 lang);
|
||||
|
||||
void setCustNr(const QString& cust_nr);
|
||||
void setGroupNr(const QString& group_nr);
|
||||
void setZoneNr(const QString& zone_nr);
|
||||
void setMachineNr(const QString& machine_nr);
|
||||
|
||||
void reReadSettings();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
enum class OOO_MODE : quint8 {
|
||||
DEFAULT = 0,
|
||||
USE_PARKDISK = 1,
|
||||
USE_OTHER_MACHINE = 2
|
||||
};
|
||||
|
||||
#endif // ATBHMICONFIG_H
|
2745
AppControl.cpp
Normal file
2745
AppControl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
242
AppControl.h
Normal file
242
AppControl.h
Normal file
@ -0,0 +1,242 @@
|
||||
#ifndef APPCONTROL_H
|
||||
#define APPCONTROL_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "version.h"
|
||||
#include "atb_system.h"
|
||||
#include "ATBAPP.h"
|
||||
#include "plugins/PluginManager.h"
|
||||
#include "plugins/CC/CCInterface.h"
|
||||
#include "plugins/CalculatePrice/CalculatePriceInterface.h"
|
||||
|
||||
#include "support/VendingData.h"
|
||||
#include "CalculatePrice/CalculatePriceDefault.h"
|
||||
|
||||
class VMC;
|
||||
class ATBHMIconfig;
|
||||
class VendingData;
|
||||
class QTimer;
|
||||
|
||||
class AppControl : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppControl(QObject *parent = nullptr);
|
||||
|
||||
PROGRAM_MODE getCurrentProgramMode();
|
||||
bool requestProgramMode(PROGRAM_MODE newProgramMode);
|
||||
|
||||
bool isProgramModeSELL();
|
||||
bool isProgramModeSELL_ENABLE();
|
||||
bool isProgramModeSERVICE();
|
||||
bool isProgramModeIDLE();
|
||||
bool isProgramModeOOO();
|
||||
|
||||
public slots:
|
||||
void onRequestOfflineProcessing();
|
||||
|
||||
// e.g. by button event,
|
||||
// by vmc screen command,
|
||||
// by vmc data display command
|
||||
// ...
|
||||
void restartSellModeTimeoutTimer();
|
||||
|
||||
// slots for LED configuration:
|
||||
void LEDs_default();
|
||||
void LEDs_ooo();
|
||||
|
||||
// CC-Plugin
|
||||
void onCCStartTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCConfirmTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCCancelTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCRevertTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCBookTotalTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCCancelPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void onCCRequestCardInfoResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
|
||||
// CalculatePricePlugin
|
||||
#ifdef USE_CALCULATEPRICE_PLUGIN
|
||||
void onCalculatePrice(QString & licensePlate);
|
||||
void onCalculatePrice(uint parktime);
|
||||
void onCalculatePrice(QString & cardInfo, QString & cardTransactionInfo);
|
||||
void onCalculatePrice();
|
||||
void onCalculatedPrice(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const PriceInfo & priceInfo,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
void onProcessTransaction(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
QChar private_getAccessInformationField(const QString & accessInformationType);
|
||||
QString private_calculatedPrice(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const PriceInfo & priceInfo,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
#endif // USE_CALCULATEPRICE_PLUGIN
|
||||
|
||||
|
||||
|
||||
// vmc control
|
||||
void onVMCFormatedString(FormatedStringList data);
|
||||
void onVMCSellData(quint8 nr,QString data);
|
||||
|
||||
// deprecated vmc control for cc
|
||||
// this allows cc control by screens
|
||||
void onVMC_ccStartTransaction();
|
||||
void onVMC_ccCancelTransaction();
|
||||
void onVMC_ccConfirmTransaction();
|
||||
void onVMC_ccStartPreauthorisation();
|
||||
void onVMC_ccCancelPreauthorisation();
|
||||
void onVMC_ccConfirmPreauthorisation();
|
||||
void onVMC_ccStartReadCard();
|
||||
|
||||
// new control interface
|
||||
void onControl_switchMode(quint16 mode);
|
||||
void onControl_switchScreen(quint16 screen);
|
||||
void onControl_setText(quint16 screenNr, quint16 textNr, quint16 lang, QString text);
|
||||
void onShowCurrentIdle();
|
||||
void onShowCurrentOOO();
|
||||
|
||||
// vendingData
|
||||
void onSetVendingData(QString key, QByteArray value);
|
||||
|
||||
|
||||
signals:
|
||||
// signals for signaling a mode change to sub-modules:
|
||||
void changedProgramMode(PROGRAM_MODE newProgramMode);
|
||||
void changedModeToSELL();
|
||||
void changedModeToSERVICE();
|
||||
void changedModeToIDLE();
|
||||
void changedModeToOOO();
|
||||
|
||||
void doOfflineProcessing();
|
||||
|
||||
// cc
|
||||
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
|
||||
private:
|
||||
PROGRAM_MODE programmode;
|
||||
ATBHMIconfig *config;
|
||||
ATB_system *system;
|
||||
VMC *vmc;
|
||||
VendingData *vendingData;
|
||||
|
||||
PluginManager *pluginManager;
|
||||
|
||||
void private_setupProgramModeSELL();
|
||||
void private_setupProgramModeSELL_ENABLE();
|
||||
void private_setupProgramModeSERVICE();
|
||||
void private_setupProgramModeIDLE();
|
||||
void private_setupProgramModeOOO();
|
||||
void private_unsetProgramModeSERVICE();
|
||||
void private_unsetProgramModeOOO();
|
||||
|
||||
// plugins
|
||||
CCInterface *cc;
|
||||
CalculatePriceInterface *calcPriceBackend;
|
||||
|
||||
// init methods called from constructor
|
||||
void private_initCCPlugin();
|
||||
void private_initCalculatePricePlugin();
|
||||
void private_initSimulationPlugin();
|
||||
|
||||
// timers
|
||||
QTimer *sellModeTimeoutTimer;
|
||||
|
||||
// flag to prepare for OOO in next idle
|
||||
quint8 prepareInternalOOO;
|
||||
|
||||
// action processing
|
||||
quint8 startAction(APP_ACTION action);
|
||||
|
||||
#if defined (ARCH_DesktopLinux)
|
||||
void private_screenshot();
|
||||
#endif
|
||||
|
||||
#if defined (CUST00318)
|
||||
// hack for 00318/Nexobility
|
||||
void private_CUST00318_handle_CC_ERROR_0x13();
|
||||
#endif
|
||||
|
||||
// mouse detection
|
||||
#if defined (ARCH_PTU4)
|
||||
QFileSystemWatcher *pInputDeviceWatcher;
|
||||
void setMouse(const QString & mouseDeviceFile, const QString & touchDeviceFile);
|
||||
void closeMouse(const QString & mouseDeviceFile, const QString & touchDeviceFile);
|
||||
bool mousePresent;
|
||||
#endif
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
// firstRun -> things done with running event loop
|
||||
void firstRun();
|
||||
|
||||
// timers
|
||||
void onSellModeTimerTimeout();
|
||||
|
||||
|
||||
/********************************************
|
||||
* CC - Slots
|
||||
*/
|
||||
void onCCStartTransaction();
|
||||
void onCCStartConfirmTransaction();
|
||||
void onCCCancelTransaction();
|
||||
|
||||
void onCCStartPreauthorisation();
|
||||
void onCCConfirmPreauthorisation();
|
||||
void onCCCancelPreauthorisationRequest();
|
||||
|
||||
void onCCPrintReceipt();
|
||||
|
||||
void onCCErrorBackend(QString & result);
|
||||
|
||||
void onCCStartReadCard();
|
||||
/*******************************************/
|
||||
|
||||
|
||||
// called, if system was woken up
|
||||
void onWakeUp();
|
||||
|
||||
|
||||
/********************************************
|
||||
* Barcode / QR-Code - Slots
|
||||
*/
|
||||
#ifdef USE_BARCODESCANNER
|
||||
// called, if a barcode was read from scanner
|
||||
void onReadBarcode(QString & barcode);
|
||||
|
||||
// called, if a new barcode should be created and sent to vmc
|
||||
void onRequestNewBarcode();
|
||||
#endif
|
||||
/*******************************************/
|
||||
|
||||
#if defined (Q_WS_QWS)
|
||||
void onInputDeviceWatcher_directoryChanged(const QString& path);
|
||||
#endif
|
||||
|
||||
/********************************************
|
||||
* ISMAS
|
||||
*/
|
||||
void onProcessed_QRCode(QHash<QString, QByteArray> data);
|
||||
|
||||
/********************************************
|
||||
* Signal System Errors
|
||||
*/
|
||||
void onSignalSystemErrors(const QString & errorCode, const QString & errorDescription);
|
||||
};
|
||||
|
||||
#endif // APPCONTROL_H
|
103
VMCPlugin.pro
103
VMCPlugin.pro
@ -0,0 +1,103 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
QT += gui
|
||||
QT += serialport
|
||||
|
||||
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/support
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/plugins
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/include
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/HMI
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/HMI/screens
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/HMI/support
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/src
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/src/ATBAPP
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/src/ATBAPP/support
|
||||
INCLUDEPATH+=$$_PRO_FILE_PWD_/src/ATBAPP/support/VMC
|
||||
|
||||
QMAKE_CXXFLAGS += -Wno-deprecated-copy -O
|
||||
|
||||
# default
|
||||
ARCH = PTU5
|
||||
|
||||
DEFINES+=ATB_QT_VERSION=\\\"5.11\\\"
|
||||
|
||||
contains( CONFIG, DesktopLinux ) {
|
||||
QMAKE_CC = ccache $$QMAKE_CC
|
||||
QMAKE_CXX = ccache $$QMAKE_CXX
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
# QMAKE_CXXFLAGS += -Wno-deprecated-ctor
|
||||
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
|
||||
ARCH = DesktopLinux
|
||||
}
|
||||
|
||||
contains( CONFIG, PTU5 ) {
|
||||
# QMAKE_CC = ccache $$QMAKE_CC
|
||||
# QMAKE_CXX = ccache $$QMAKE_CXX
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
|
||||
CONFIG += link_pkgconfig
|
||||
ARCH = PTU5
|
||||
}
|
||||
|
||||
contains( CONFIG, PTU5_YOCTO ) {
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
|
||||
PTU5BASEPATH = /opt/devel/ptu5
|
||||
ARCH = PTU5
|
||||
|
||||
# add qmqtt lib
|
||||
#LIBS += -lQt5Qmqtt
|
||||
}
|
||||
|
||||
TARGET = ATBVMCPlugin
|
||||
#DESTDIR = ../plugins
|
||||
INTERFACE = VMCInterface
|
||||
INTERFACE_DEFINITION = $${PWD}/src/ATBAPP/VMCInterface.h
|
||||
|
||||
DEFINES += VMCPLUGIN_LIBRARY
|
||||
|
||||
# Default rules for deployment.
|
||||
#qnx: target.path = /tmp/$${TARGET}/bin
|
||||
#else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
#!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
# ATBAPP interface
|
||||
HEADERS += \
|
||||
AppControl.h \
|
||||
ATBHMIconfig.h \
|
||||
atb_system.h \
|
||||
include/interfaces.h \
|
||||
src/ATBAPP/VMCInterface.h \
|
||||
src/ATBAPP/ATBVMCPlugin.h \
|
||||
src/ATBAPP/UnifiedDCVMCInterface.h \
|
||||
src/ATBAPP/support/VMC/com_interface.h \
|
||||
src/ATBAPP/support/VMC/ReceiveBuffer.h \
|
||||
src/ATBAPP/support/VMC/SendBuffer.h \
|
||||
src/ATBAPP/support/VMC/vmc.h \
|
||||
src/ATBAPP/support/VendingData.h
|
||||
|
||||
SOURCES += \
|
||||
atb_system.cpp \
|
||||
AppControl.cpp \
|
||||
ATBHMIconfig.cpp \
|
||||
src/ATBAPP/ATBVMCPlugin.cpp \
|
||||
src/ATBAPP/support/VMC/com_interface.cpp \
|
||||
src/ATBAPP/support/VMC/ReceiveBuffer.cpp \
|
||||
src/ATBAPP/support/VMC/SendBuffer.cpp \
|
||||
src/ATBAPP/support/VMC/vmc.cpp \
|
||||
src/ATBAPP/support/VendingData.cpp
|
||||
|
||||
DISTFILES += \
|
||||
generate-version.sh
|
||||
|
||||
|
||||
# Define how to create version.h
|
||||
VERSION_H = $$PWD/include/version.h
|
||||
version.output = $$PWD/include/version.h
|
||||
version.commands = $$PWD/generate-version.sh $${ARCH} $${TARGET} $${INTERFACE} $${INTERFACE_DEFINITION} $${VERSION_H}
|
||||
version.depends = FORCE
|
||||
version.input = VERSION_H
|
||||
version.variable_out = HEADERS
|
||||
QMAKE_EXTRA_COMPILERS += version
|
||||
QMAKE_CLEAN += $${PWD}/include/version.h
|
723
atb_system.cpp
Normal file
723
atb_system.cpp
Normal file
@ -0,0 +1,723 @@
|
||||
#include "atb_system.h"
|
||||
#include "ATBHMIconfig.h"
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
ATB_system::ATB_system(ATBHMIconfig *config, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
this->config = config;
|
||||
|
||||
this->tf_gpio = nullptr;
|
||||
|
||||
#if defined (ARCH_PTU2)
|
||||
if (config->hasFeatureTF()) init_touch_feedback();
|
||||
#elif defined (ARCH_PTU4)
|
||||
if (config->hasFeatureTF()) init_touch_feedback();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
ATB_system::~ATB_system()
|
||||
{
|
||||
if (config->hasFeatureTF()) {
|
||||
delete(this->tf_gpio_outstream);
|
||||
delete(this->tf_gpio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ATB_system::executeSystemCommand(quint16 cmd, QByteArray data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
|
||||
switch (cmd) {
|
||||
case SYS_COMMAND_SLEEP:
|
||||
qDebug() << "ATB_system::executeSystemCommand(): " << cmd;
|
||||
dbus_permitSuspend();
|
||||
break;
|
||||
case SYS_COMMAND_DIMLOW:
|
||||
if (config->hasFeatureDBusDisplayControl()) {
|
||||
dbus_DimControlStart();
|
||||
} else {
|
||||
this->DimLow();
|
||||
}
|
||||
break;
|
||||
case SYS_COMMAND_DIMHIGH:
|
||||
if (config->hasFeatureDBusDisplayControl()) {
|
||||
dbus_DimHighPermanent();
|
||||
} else {
|
||||
this->DimHigh();
|
||||
}
|
||||
break;
|
||||
case SYS_COMMAND_BEEP:
|
||||
if (config->hasFeatureTF()) this->Beep();
|
||||
break;
|
||||
case SYS_COMMAND_MACHINE_NUMBER: // deprecated and not used
|
||||
// setMachineNumber(data);
|
||||
break;
|
||||
case SYS_COMMAND_LED_CONTROL:
|
||||
this->privateConfigLED(data);
|
||||
break;
|
||||
case SYS_COMMAND_HALT:
|
||||
this->halt();
|
||||
break;
|
||||
case SYS_COMMAND_REBOOT:
|
||||
this->reboot();
|
||||
break;
|
||||
default:
|
||||
qDebug() << "ATB_system::executeSystemCommand(): unknown command: " << cmd;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* stubs for display control
|
||||
*
|
||||
* this methodes should later be scriptable an call corresponding methodes
|
||||
* in DisplayControl via DBus.
|
||||
*/
|
||||
|
||||
void ATB_system::DimLow() { return; }
|
||||
|
||||
void ATB_system::DimHigh()
|
||||
{
|
||||
//if (config->hasFeatureDC())
|
||||
// this->dc->DimHigh();
|
||||
}
|
||||
|
||||
//void ATB_system::Dim(quint8 value) { if (config->hasFeatureDC()) this->dc->Dim((uchar)value); }
|
||||
|
||||
void ATB_system::DimStart() { return; }
|
||||
void ATB_system::DimStop() { return; }
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*/
|
||||
|
||||
void ATB_system::Beep() {
|
||||
qDebug() << "ATB_system::Beep(): now i should make a beep!";
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QTimer::singleShot (BEEPTIMEOUT, this, SLOT(BeepStop()) );
|
||||
*(this->tf_gpio_outstream) << config->getTouchFeedbackOnValue();
|
||||
this->tf_gpio_outstream->flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ATB_system::BeepStop() {
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
*(this->tf_gpio_outstream) << config->getTouchFeedbackOffValue();
|
||||
this->tf_gpio_outstream->flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int ATB_system::init_touch_feedback() {
|
||||
#if defined (ARCH_PTU2)
|
||||
QString GPIODirName("/sys/class/gpio/");
|
||||
QString directionFileName;
|
||||
QString valueFileName;
|
||||
|
||||
// # echo 129 > /sys/class/gpio/export
|
||||
QFile file("/sys/class/gpio/export");
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out << config->getTouchFeedbackGPIO();
|
||||
file.close();
|
||||
|
||||
// check, if gpio-dir was created
|
||||
GPIODirName.append("gpio");
|
||||
GPIODirName.append(config->getTouchFeedbackGPIO());
|
||||
QFileInfo fileinfo1(GPIODirName);
|
||||
if (! fileinfo1.isDir() ) {
|
||||
qDebug() << "ATB_system::init_touch_feedback(): \"" << GPIODirName << "\" is not a directory";
|
||||
config->unsetFeatureTF();
|
||||
return -1;
|
||||
}
|
||||
directionFileName = GPIODirName + "/direction";
|
||||
QFileInfo fileinfo2(directionFileName);
|
||||
if (! fileinfo2.isWritable() ) {
|
||||
qDebug() << "ATB_system::init_touch_feedback(): \"" << directionFileName << "\" is not writable";
|
||||
config->unsetFeatureTF();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// # echo out > /sys/class/gpio/gpio129/direction
|
||||
QFile directionfile(directionFileName);
|
||||
directionfile.open(QIODevice::ReadWrite | QIODevice::Text);
|
||||
QTextStream out2(&directionfile);
|
||||
out2 << "out";
|
||||
out2.flush();
|
||||
|
||||
// re-read 'direction' for confirmation
|
||||
// -> the following is disabled because this sometimes failed
|
||||
//QTextStream in(&directionfile);
|
||||
//QString line = in.readLine();
|
||||
//if (line != "out") {
|
||||
// qDebug() << "ATB_system::init_touch_feedback(): re-read directionfile failed";
|
||||
// config->unsetFeatureTF();
|
||||
// return -1;
|
||||
//}
|
||||
directionfile.close();
|
||||
|
||||
// open gpio file
|
||||
valueFileName = GPIODirName + "/value";
|
||||
this->tf_gpio = new QFile(valueFileName);
|
||||
|
||||
this->tf_gpio->open(QIODevice::WriteOnly);
|
||||
this->tf_gpio_outstream = new QTextStream(this->tf_gpio);
|
||||
|
||||
qDebug() << "ATB_system::init_touch_feedback(): GPIODirName = \"" << GPIODirName << "\"";
|
||||
qDebug() << "ATB_system::init_touch_feedback(): valueFileName = \"" << valueFileName << "\"";
|
||||
|
||||
#elif defined (ARCH_PTU4)
|
||||
QString sysfs_buzzer("/sys/class/leds/Buzzer/brightness");
|
||||
|
||||
this->tf_gpio = new QFile(sysfs_buzzer);
|
||||
tf_gpio->open(QIODevice::WriteOnly);
|
||||
|
||||
this->tf_gpio_outstream = new QTextStream(this->tf_gpio);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* set date/time
|
||||
*
|
||||
* Datestring format: YYYY-MM-DD hh:mm[:ss]
|
||||
* This is a format that is accepted both by busybox-date (e.g. PTU2) and by
|
||||
* coreutils-date.
|
||||
*
|
||||
* example:
|
||||
* /bin/date -s "2015-08-05 17:55:00"
|
||||
*
|
||||
*/
|
||||
void ATB_system::setDateTime(const QString & dateTimeString)
|
||||
{
|
||||
QString datetimeCMD = "/bin/date -s " + dateTimeString;
|
||||
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QProcess::startDetached(datetimeCMD);
|
||||
|
||||
// the following does not work on PTU2:
|
||||
//QProcess::startDetached ("/sbin/hwclock -w");
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* static functions to write single values to files.
|
||||
*
|
||||
* Used e.g. to store some machine specific settings like customer number or machine
|
||||
* number in filesystem.
|
||||
*
|
||||
* This data should be updated rarely and the calling function must keep this in mind!
|
||||
*
|
||||
* Note: QFile::open() creates a file, if it is not existing.
|
||||
*/
|
||||
|
||||
quint8 ATB_system::setPSAConfigInt(const QString &filename, quint16 iValue)
|
||||
{
|
||||
return setPSAConfigString(filename, QString::number(iValue));
|
||||
}
|
||||
|
||||
|
||||
quint8 ATB_system::setPSAConfigString(const QString & filename, const QString & sValue)
|
||||
{
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFile file(filename);
|
||||
#else
|
||||
QFile file(QDir::homePath() + filename);
|
||||
#endif
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::setPSAConfigString() cannot open file: " << filename;
|
||||
qDebug() << " file.errorString() = " << file.errorString();
|
||||
return 0;
|
||||
}
|
||||
|
||||
qDebug() << "ATB_system::setPSAConfigString() write file: " << filename;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << sValue;
|
||||
out.flush();
|
||||
|
||||
file.close();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
quint16 ATB_system::readPSAConfigInt(const QString & filename)
|
||||
{
|
||||
bool ok;
|
||||
quint16 result = (quint16)readPSAConfigString(filename).toInt(&ok);
|
||||
|
||||
if (!ok) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString ATB_system::readPSAConfigString(const QString & filename)
|
||||
{
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFileInfo fileinfo(filename);
|
||||
#else
|
||||
QFileInfo fileinfo(QDir::homePath() + filename);
|
||||
#endif
|
||||
if (! fileinfo.isReadable() ) {
|
||||
qDebug() << "ATB_system::readPSAConfigString(): \"" << filename << "\" is not readable";
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFile file(filename);
|
||||
#else
|
||||
QFile file(QDir::homePath() + filename);
|
||||
#endif
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::readPSAConfigString() cannot open file: " << filename;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
|
||||
QString stringValue = in.readLine(100);
|
||||
qDebug() << "ATB_system::readPSAConfigString() stringValue = " << stringValue;
|
||||
|
||||
file.close();
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* LED control interface
|
||||
*
|
||||
*/
|
||||
void ATB_system::onConfigLED(LED_NAME LED, LED_TRIGGER trigger, quint16 delayOn, quint16 delayOff)
|
||||
{
|
||||
QString LEDPath = "/sys/class/leds/";
|
||||
QString LEDName = "";
|
||||
QString LEDtrigger = "";
|
||||
|
||||
// DEBUG
|
||||
|
||||
|
||||
|
||||
// ////////
|
||||
|
||||
|
||||
switch (LED) {
|
||||
#if defined (ARCH_PTU2)
|
||||
case ATB_LED1: LEDName.append("atb_led1"); break;
|
||||
case ATB_LED2: LEDName.append("atb_led2"); break;
|
||||
case ATB_LED3: LEDName.append("atb_led3"); break;
|
||||
case ATB_LED4: LEDName.append("atb_led4"); break;
|
||||
#elif defined (ARCH_PTU4)
|
||||
case ATB_LED1: LEDName.append("D504"); break;
|
||||
case ATB_LED2: LEDName.append("D503"); break;
|
||||
case ATB_LED3: LEDName.append("D502"); break;
|
||||
case ATB_LED4: LEDName.append("D501"); break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
switch (trigger) {
|
||||
case LED_TRIGGER_NONE: LEDtrigger.append("none"); break;
|
||||
case LED_TRIGGER_TIMER: LEDtrigger.append("timer"); break;
|
||||
#if defined (ARCH_PTU2)
|
||||
case LED_TRIGGER_DEFAULT_ON: LEDtrigger.append("default-on"); break;
|
||||
#elif defined (ARCH_PTU4)
|
||||
/* note: ptu4 leds currently do not support 'default-on' trigger
|
||||
* workaround is to set delay_off to '0'
|
||||
*/
|
||||
case LED_TRIGGER_DEFAULT_ON: LEDtrigger.append("timer");
|
||||
trigger = LED_TRIGGER_TIMER;
|
||||
delayOn = 1;
|
||||
delayOff = 0;
|
||||
break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
QString filename = LEDPath + LEDName + "/trigger";
|
||||
|
||||
// set trigger
|
||||
this->privateSetLEDTrigger(filename, LEDtrigger);
|
||||
|
||||
|
||||
// set delays for trigger 'timer'
|
||||
if (trigger == LED_TRIGGER_TIMER) {
|
||||
|
||||
// set delay on
|
||||
if (delayOn != 0) {
|
||||
filename = LEDPath + LEDName + "/delay_on";
|
||||
this->privateSetLEDDelayOn(filename, QString::number(delayOn));
|
||||
}
|
||||
|
||||
// set delay off
|
||||
if (delayOff != 0) {
|
||||
filename = LEDPath + LEDName + "/delay_off";
|
||||
this->privateSetLEDDelayOn(filename, QString::number(delayOff));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* wrapper function for LED control.
|
||||
*
|
||||
* TODO: Test, check: plausibillity, cmd.lenght(), type casts to LED_NAME, LED_TRIGGER
|
||||
*/
|
||||
void ATB_system::privateConfigLED(const QByteArray & cmd)
|
||||
{
|
||||
quint16 delayOn = (quint8)cmd.at(3) + ((quint16)(cmd.at(2) << 8));
|
||||
quint16 delayOff = (quint8)cmd.at(5) + ((quint16)(cmd.at(4) << 8));
|
||||
|
||||
this->onConfigLED((LED_NAME)cmd.at(0), (LED_TRIGGER)cmd.at(1), delayOn, delayOff);
|
||||
}
|
||||
|
||||
void ATB_system::privateSetLEDTrigger(const QString & led, const QString & trigger)
|
||||
{
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFile file(led);
|
||||
#else
|
||||
QFile file(QDir::homePath() + led);
|
||||
#endif
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::onConfigLED() cannot open file: " << led;
|
||||
qDebug() << " file.errorString() = " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "ATB_system::onConfigLED() write file: " << led;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << trigger;
|
||||
out.flush();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
void ATB_system::privateSetLEDDelayOn(const QString & led, const QString & delayOn)
|
||||
{
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFile file(led);
|
||||
#else
|
||||
QFile file(QDir::homePath() + led);
|
||||
#endif
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::onConfigLED() cannot open file: " << led;
|
||||
qDebug() << " file.errorString() = " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "ATB_system::onConfigLED() write file: " << led;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << delayOn;
|
||||
out.flush();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
void ATB_system::privateSetLEDDelayOff(const QString & led, const QString & delayOff)
|
||||
{
|
||||
#if defined (ARCH_PTU2) || defined (ARCH_PTU4)
|
||||
QFile file(led);
|
||||
#else
|
||||
QFile file(QDir::homePath() + led);
|
||||
#endif
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::onConfigLED() cannot open file: " << led;
|
||||
qDebug() << " file.errorString() = " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "ATB_system::onConfigLED() write file: " << led;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << delayOff;
|
||||
out.flush();
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* functions for switching blink button on/off
|
||||
* This is only available on PTU4
|
||||
*/
|
||||
void ATB_system::switchBlinkButtonOn()
|
||||
{
|
||||
this->privateSwitchBlinkButton(true);
|
||||
}
|
||||
|
||||
void ATB_system::switchBlinkButtonOff()
|
||||
{
|
||||
this->privateSwitchBlinkButton(false);
|
||||
}
|
||||
|
||||
void ATB_system::privateSwitchBlinkButton(bool on)
|
||||
{
|
||||
#if defined (ARCH_PTU2)
|
||||
|
||||
#elif defined (ARCH_PTU4)
|
||||
QString BlinkLED("/sys/class/leds/TIMER_RESET/brightness");
|
||||
|
||||
QFile file(BlinkLED);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug() << "ATB_system::privateSwitchBlinkButton() cannot open file: " << BlinkLED;
|
||||
qDebug() << " file.errorString() = " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
|
||||
if (on) { out << "0"; }
|
||||
else { out << "1"; }
|
||||
|
||||
out.flush();
|
||||
|
||||
file.close();
|
||||
|
||||
|
||||
#else
|
||||
Q_UNUSED(on)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* halt system.
|
||||
*
|
||||
*/
|
||||
void ATB_system::halt()
|
||||
{
|
||||
QProcess::startDetached("/sbin/halt");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* reboot system.
|
||||
*
|
||||
*/
|
||||
void ATB_system::reboot()
|
||||
{
|
||||
QProcess::startDetached("/sbin/reboot");
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* functions for wake vmc
|
||||
* This is only available on PTU4
|
||||
*/
|
||||
void ATB_system::onWakeVMC()
|
||||
{
|
||||
#if defined (ARCH_PTU2)
|
||||
|
||||
#elif defined (ARCH_PTU4)
|
||||
if (config->hasFeatureDBusSuspendControl()) {
|
||||
this->dbus_wakeSystem();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* get event device name by a type:
|
||||
*
|
||||
* e.g. type is TOUCHSCREEN:
|
||||
* getEventDeviceName(TOUCHSCREEN) returns "/dev/input/event0"
|
||||
*
|
||||
*/
|
||||
QString ATB_system::getEventDeviceName(DEVICE_TYPE type)
|
||||
{
|
||||
QString procDevices = "/proc/bus/input/devices";
|
||||
|
||||
QFile inFile(procDevices);
|
||||
if (!inFile.open(QFile::ReadOnly)) {
|
||||
qCritical() << "ATB_system::getEventDeviceName() ERROR open()" << procDevices;
|
||||
return "";
|
||||
}
|
||||
|
||||
QTextStream textInStream(&inFile);
|
||||
QString line;
|
||||
QString N_RegExp;
|
||||
QString DeviceTypeName;
|
||||
int lineCounter = 0;
|
||||
bool typeFound = false;
|
||||
QString H_RegExp = "^H: Handlers"; // H: Handlers=kbd event2
|
||||
QString eventDeviceName = "";
|
||||
QString eventPart;
|
||||
QStringList devNames;
|
||||
QString DeviceNamePattern;
|
||||
|
||||
//PTU4 Touchscreen N: Name="atmel_mxt_ts T100 touchscreen"
|
||||
//PTU4 GPIO kys N: Name="gpio_keys.6"
|
||||
//RFID Reader, Stronglink SL040 N: Name="StrongLink USB CardReader"
|
||||
//2D Scanner, Datalogig DSE0420 N: Name="Datalogic ADC Inc. Handheld Barcode Scanner" VID: 05f9, PID:4005
|
||||
//2D Scanner, Datalogig DSM0400 N: Name="Datalogic Handheld Barcode Scanner" VID: 05f9, PID:4005
|
||||
//2D Scanner, Honeywell N56000 N: Name="Honeywell Imaging & Mobility N5600"
|
||||
//2D Scanner, Newland FM3080 N: Name="Newland Auto-ID NLS-FM3080V2-20 USB POS KBW" VID: 1eab, PID:0022
|
||||
//2D Scanner, Opticon MDI-4000 N: Name="Opticon Opticon USB Barcode Reader"
|
||||
//USB Mouse N: Name="Logitech USB-PS/2 Optical Mouse"
|
||||
|
||||
/* Datalogic DSE0420
|
||||
I: Bus=0003 Vendor=05f9 Product=4005 Version=0110
|
||||
N: Name="Datalogic ADC Inc. Handheld Barcode Scanner"
|
||||
P: Phys=usb-700000.ehci-2.3/input2
|
||||
S: Sysfs=/devices/ahb.0/700000.ehci/usb1/1-2/1-2.3/1-2.3:1.2/input/input14
|
||||
U: Uniq=S/N G16C15795
|
||||
H: Handlers=kbd event3
|
||||
B: PROP=0
|
||||
B: EV=120013
|
||||
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
|
||||
B: MSC=10
|
||||
B: LED=1f
|
||||
*/
|
||||
/* Datalogic DSM04XX
|
||||
I: Bus=0003 Vendor=05f9 Product=4005 Version=0110
|
||||
N: Name="Datalogic Handheld Barcode Scanner"
|
||||
P: Phys=usb-700000.ehci-2.3/input0
|
||||
S: Sysfs=/devices/ahb.0/700000.ehci/usb1/1-2/1-2.3/1-2.3:1.0/input/input15
|
||||
U: Uniq=S/N G21FA0180
|
||||
H: Handlers=kbd event3
|
||||
B: PROP=0
|
||||
B: EV=120013
|
||||
B: KEY=e080ffdf 1cfffff ffffffff fffffffe
|
||||
B: MSC=10
|
||||
B: LED=1f
|
||||
*/
|
||||
/*
|
||||
I: Bus=0003 Vendor=1eab Product=0022 Version=0110
|
||||
N: Name="Newland Auto-ID NLS-FM3080V2-20 USB POS KBW"
|
||||
P: Phys=usb-700000.ehci-2.2/input0
|
||||
S: Sysfs=/devices/ahb.0/700000.ehci/usb1/1-2/1-2.2/1-2.2:1.0/input/input6
|
||||
U: Uniq=FM3080V2-20-BH00017
|
||||
H: Handlers=kbd event2
|
||||
B: PROP=0
|
||||
B: EV=120013
|
||||
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
|
||||
B: MSC=10
|
||||
B: LED=1f
|
||||
*/
|
||||
|
||||
|
||||
switch (type) {
|
||||
case EVENT_DEVICE_BARCODEREADER:
|
||||
N_RegExp = "^N: Name=.+(Barcode|Honeywell Imaging|Newland Auto).+";
|
||||
DeviceTypeName = "1D/2D-Scanner";
|
||||
DeviceNamePattern = "event";
|
||||
break;
|
||||
case EVENT_DEVICE_TOUCHSCREEN:
|
||||
N_RegExp = "^N: Name=.+touch.+";
|
||||
DeviceTypeName = "Touchscreen";
|
||||
DeviceNamePattern = "event";
|
||||
break;
|
||||
case EVENT_DEVICE_GPIO_KEYBOARD:
|
||||
N_RegExp = "^N: Name=.+gpio.+";
|
||||
DeviceTypeName = "gpio-keys";
|
||||
DeviceNamePattern = "event";
|
||||
break;
|
||||
case EVENT_DEVICE_KEYBOARD:
|
||||
N_RegExp = "^N: Name=.+touch.+";
|
||||
DeviceTypeName = "keyboard";
|
||||
DeviceNamePattern = "event";
|
||||
break;
|
||||
case EVENT_DEVICE_RFIDREADER:
|
||||
N_RegExp = "^N: Name=.+Card.+";
|
||||
DeviceTypeName = "card reader";
|
||||
DeviceNamePattern = "event";
|
||||
break;
|
||||
case EVENT_DEVICE_USBMOUSE:
|
||||
N_RegExp = "^N: Name=.+USB.+Mouse.+";
|
||||
DeviceTypeName = "USB Mouse";
|
||||
DeviceNamePattern = "mouse";
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "ATB_system::getEventDeviceName() N_RegExp = " << N_RegExp;
|
||||
|
||||
do {
|
||||
line = textInStream.readLine();
|
||||
|
||||
// DEBUG
|
||||
//qDebug() << " " << line;
|
||||
|
||||
// find "N:"-line:
|
||||
if (line.contains(QRegExp(N_RegExp))) {
|
||||
typeFound = true;
|
||||
lineCounter = 0;
|
||||
|
||||
qDebug() << "ATB_system::getEventDeviceName() found N_RegExp = " << N_RegExp;
|
||||
|
||||
}
|
||||
|
||||
if (typeFound) {
|
||||
// found "N:"-line, now search for "H:"-line;
|
||||
// the corresponding "H:"-line should be within the next 7 following text lines.
|
||||
|
||||
// example lines:
|
||||
// - "H: Handlers=event0 mouse0" -> for touchscreen on PTU4
|
||||
// - "H: Handlers=event3 mouse1" -> for USB mouse on PTU4
|
||||
|
||||
lineCounter++;
|
||||
if ( (lineCounter<=7) && (line.contains(QRegExp(H_RegExp))) ) {
|
||||
eventPart = line.split("=", QString::SkipEmptyParts).takeLast();
|
||||
devNames = eventPart.split(" ", QString::SkipEmptyParts);
|
||||
|
||||
for (int i=0; i<devNames.size(); i++ ) {
|
||||
|
||||
if (devNames.at(i).contains(DeviceNamePattern)) {
|
||||
eventDeviceName = "/dev/input/" + devNames.at(i);
|
||||
|
||||
qDebug() << "ATB_system::getEventDeviceName() found device = " << eventDeviceName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if ( lineCounter>7 ) {
|
||||
lineCounter=0;
|
||||
typeFound = false;
|
||||
}
|
||||
}
|
||||
} while (!line.isNull());
|
||||
|
||||
if (eventDeviceName == "") {
|
||||
qCritical() << "ATB_system::getEventDeviceName(): could not detect input event device type " << DeviceTypeName;
|
||||
}
|
||||
|
||||
return eventDeviceName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
120
atb_system.h
Normal file
120
atb_system.h
Normal file
@ -0,0 +1,120 @@
|
||||
#ifndef ATB_SYSTEM_H
|
||||
#define ATB_SYSTEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#define SYS_COMMAND_SLEEP 0x0001
|
||||
#define SYS_COMMAND_DIMLOW 0x0002
|
||||
#define SYS_COMMAND_DIMHIGH 0x0003
|
||||
#define SYS_COMMAND_BEEP 0x0004
|
||||
#define SYS_COMMAND_MACHINE_NUMBER 0x0005
|
||||
#define SYS_COMMAND_HALT 0x0006
|
||||
#define SYS_COMMAND_REBOOT 0x0007
|
||||
#define SYS_COMMAND_LED_CONTROL 0x3600
|
||||
|
||||
|
||||
#if defined (ARCH_PTU2)
|
||||
#define BEEPTIMEOUT 200
|
||||
#elif defined (ARCH_PTU4)
|
||||
#define BEEPTIMEOUT 100
|
||||
#else
|
||||
#define BEEPTIMEOUT 100
|
||||
#endif
|
||||
|
||||
class ATBHMIconfig;
|
||||
|
||||
class ATB_system : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
int init_touch_feedback();
|
||||
int init_sc_dbus();
|
||||
|
||||
ATBHMIconfig *config;
|
||||
QFile *tf_gpio;
|
||||
QTextStream *tf_gpio_outstream;
|
||||
|
||||
quint8 current_dim_value;
|
||||
|
||||
void privateConfigLED(const QByteArray & cmd);
|
||||
void privateSetLEDTrigger(const QString & led, const QString & trigger);
|
||||
void privateSetLEDDelayOn(const QString & led, const QString & delayOn);
|
||||
void privateSetLEDDelayOff(const QString & led, const QString & delayOff);
|
||||
void privateSwitchBlinkButton(bool on);
|
||||
|
||||
public:
|
||||
explicit ATB_system(ATBHMIconfig *config, QObject *parent = nullptr);
|
||||
~ATB_system();
|
||||
|
||||
|
||||
static quint8 setPSAConfigInt(const QString & filename, quint16 iValue);
|
||||
static quint16 readPSAConfigInt(const QString &filename);
|
||||
|
||||
static quint8 setPSAConfigString(const QString & filename, const QString & sValue);
|
||||
static QString readPSAConfigString(const QString & filename);
|
||||
|
||||
enum LED_NAME {
|
||||
ATB_LED1 = 1,
|
||||
ATB_LED2,
|
||||
ATB_LED3,
|
||||
ATB_LED4
|
||||
};
|
||||
|
||||
enum LED_TRIGGER {
|
||||
LED_TRIGGER_NONE = 1,
|
||||
LED_TRIGGER_TIMER,
|
||||
LED_TRIGGER_DEFAULT_ON
|
||||
};
|
||||
|
||||
enum DEVICE_TYPE {
|
||||
EVENT_DEVICE_BARCODEREADER,
|
||||
EVENT_DEVICE_TOUCHSCREEN,
|
||||
EVENT_DEVICE_GPIO_KEYBOARD,
|
||||
EVENT_DEVICE_KEYBOARD,
|
||||
EVENT_DEVICE_RFIDREADER,
|
||||
EVENT_DEVICE_USBMOUSE
|
||||
};
|
||||
|
||||
static QString getEventDeviceName(DEVICE_TYPE type);
|
||||
static quint8 setupInductionLoops();
|
||||
|
||||
|
||||
void dbus_permitSuspend();
|
||||
void dbus_preventSuspend();
|
||||
|
||||
void dbus_DimHighPermanent();
|
||||
void dbus_DimControlStart();
|
||||
|
||||
void dbus_wakeSystem();
|
||||
|
||||
signals:
|
||||
/* emitted, after waking up from suspend...
|
||||
*/
|
||||
void wakeUp();
|
||||
|
||||
public slots:
|
||||
void executeSystemCommand(quint16 cmd, QByteArray data);
|
||||
void DimHigh();
|
||||
void DimLow();
|
||||
void Dim(quint8 value);
|
||||
void DimStart();
|
||||
void DimStop();
|
||||
void Beep();
|
||||
void BeepStop();
|
||||
void setDateTime(const QString &dateTimeString);
|
||||
|
||||
void onConfigLED(LED_NAME LED, LED_TRIGGER trigger, quint16 delayOn = 0, quint16 delayOff = 0);
|
||||
|
||||
void switchBlinkButtonOn();
|
||||
void switchBlinkButtonOff();
|
||||
|
||||
void onWakeVMC();
|
||||
void halt();
|
||||
void reboot();
|
||||
};
|
||||
|
||||
#endif // ATB_SYSTEM_H
|
157
generate-version.sh
Executable file
157
generate-version.sh
Executable file
@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION_STRING=""
|
||||
|
||||
#GIT='/cygdrive/c/Program Files \(x86\)/Git/bin/git'
|
||||
GIT=git
|
||||
|
||||
|
||||
|
||||
|
||||
parse_git_branch () {
|
||||
$GIT branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1/"
|
||||
}
|
||||
|
||||
|
||||
ARCH=$1
|
||||
TARGET=$2
|
||||
INTERFACE=$3
|
||||
INTERFACE_DEFINITION=$4
|
||||
VERSION_H=$5
|
||||
|
||||
SCRIPT=$(readlink -f $0)
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
OUTPUTDIR=$(pwd)
|
||||
echo " current dir is : " $(pwd)
|
||||
echo $SCRIPT
|
||||
echo $SCRIPTPATH
|
||||
|
||||
echo "changing dir to script path: " $SCRIPTPATH
|
||||
cd $SCRIPTPATH
|
||||
|
||||
# set version string ##################################################################
|
||||
if [ -z $VERSION_STRING ] ; then
|
||||
VERSION_STRING=$(date +%Y%m%d_%H%M)
|
||||
fi
|
||||
GIT_DESCRIBE=$($GIT describe --always)
|
||||
GIT_BRANCH=$(parse_git_branch)
|
||||
|
||||
# extract path from branchname:
|
||||
IFS='_' read -ra TMP_ARRAY <<< "${GIT_BRANCH}"
|
||||
BRANCH_PATH=${TMP_ARRAY[0]}
|
||||
|
||||
|
||||
|
||||
# detect if we have a development version:
|
||||
if [ ${#TMP_ARRAY[1]} -gt 0 ] ; then
|
||||
DEV_SUFFIX="_dev"
|
||||
else
|
||||
DEV_SUFFIX=""
|
||||
fi
|
||||
|
||||
# detect if git status is dirty
|
||||
GIT_DESCRIBE_DIRTY=$($GIT describe --dirty)
|
||||
if [ "${GIT_DESCRIBE_DIRTY:(-6)}" == "-dirty" ] ; then
|
||||
DIRTY_SUFFIX="_dirty"
|
||||
else
|
||||
DIRTY_SUFFIX=""
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$DIRTY_SUFFIX" ] || [ -n "$DEV_SUFFIX" ] ; then
|
||||
DEVDIRTY=true
|
||||
else
|
||||
DEVDIRTY=false
|
||||
fi
|
||||
|
||||
|
||||
# extract interface definition
|
||||
|
||||
#
|
||||
#Q_DECLARE_INTERFACE(CCInterface,
|
||||
# "eu.atb.ptu.plugin.CCInterface/2.9.0")
|
||||
#Q_DECLARE_INTERFACE(DeviceControllerInterface,
|
||||
# "eu.atb.ptu.plugin.DeviceControllerInterface/1.0")
|
||||
# -> extract whole string within quotation marks
|
||||
INTERFACE_VERSION=$(grep 'eu.atb.ptu.plugin.' ${INTERFACE_DEFINITION})
|
||||
# get string within quotes:
|
||||
INTERFACE_VERSION=`echo ${INTERFACE_VERSION} | awk -F \" '{print $2}'`
|
||||
|
||||
|
||||
#
|
||||
# write version.h
|
||||
|
||||
|
||||
echo " TARGET is: $TARGET"
|
||||
echo " ARCH is: $ARCH"
|
||||
echo " "
|
||||
echo " PluginName: $TARGET"
|
||||
echo " Interface: $INTERFACE"
|
||||
echo " InterfaceVersion: $INTERFACE_VERSION"
|
||||
echo " "
|
||||
echo " new version is: $VERSION_STRING"
|
||||
echo " git describe is: $GIT_DESCRIBE"
|
||||
echo " git branch is: $GIT_BRANCH"
|
||||
echo " branch-path is: $BRANCH_PATH"
|
||||
echo " "
|
||||
|
||||
echo " dev suffix: $DEV_SUFFIX"
|
||||
echo " dirty suffix: $DIRTY_SUFFIX"
|
||||
|
||||
|
||||
PLUGIN_VERSION=${VERSION_STRING}
|
||||
#ATB_QT_GIT_DESCRIBE=${GIT_DESCRIBE}_${GIT_BRANCH}
|
||||
PLUGIN_GIT_DESCRIBE=${GIT_DESCRIBE}_${BRANCH_PATH}${DEV_SUFFIX}${DIRTY_SUFFIX}
|
||||
|
||||
#TARGET=IngenicoZVT_CCPlugin
|
||||
|
||||
|
||||
# build version.h #####################################################################
|
||||
|
||||
echo " building new version info (version.h) ..."
|
||||
|
||||
|
||||
|
||||
|
||||
echo "#ifndef VERSION_H" > ${VERSION_H}
|
||||
echo "#define VERSION_H" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "#define INTERFACE_VERSION \"${INTERFACE_VERSION}\"" >> ${VERSION_H}
|
||||
echo "#define PLUGIN_VERSION \"${PLUGIN_VERSION}\"" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "#define PLUGIN_GIT_DESCRIBE \"${PLUGIN_GIT_DESCRIBE}\"" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
|
||||
cat <<EOT >> ${VERSION_H}
|
||||
|
||||
const std::string pluginInfoString = R"(
|
||||
{
|
||||
"Interface": "${INTERFACE}",
|
||||
"InterfaceVersion": "${INTERFACE_VERSION}",
|
||||
"PluginName": "${TARGET}",
|
||||
"Version": "${PLUGIN_VERSION}",
|
||||
"git-describe": "${PLUGIN_GIT_DESCRIBE}",
|
||||
}
|
||||
)";
|
||||
|
||||
EOT
|
||||
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
if [ ${DEVDIRTY} == "true" ] ; then
|
||||
echo "#define DEVDIRTY" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
fi
|
||||
echo "#define SYSTEM_ARCH \"${ARCH}\"" >> ${VERSION_H}
|
||||
echo "#define ARCH_${ARCH}" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "" >> ${VERSION_H}
|
||||
echo "#endif //VERSION_H" >> ${VERSION_H}
|
||||
|
||||
|
||||
|
||||
|
||||
|
1468
include/interfaces.h
Executable file
1468
include/interfaces.h
Executable file
File diff suppressed because it is too large
Load Diff
22
plugins/ATBAPPplugin.h
Normal file
22
plugins/ATBAPPplugin.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef ATBAPPPLUGIN_H
|
||||
#define ATBAPPPLUGIN_H
|
||||
|
||||
/***********************************************************
|
||||
* a simple class with only one method for plugin info
|
||||
*/
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class ATBAPPplugin
|
||||
{
|
||||
|
||||
public:
|
||||
virtual const QString & getPluginInfo() = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(ATBAPPplugin,
|
||||
"eu.atb.ptu.plugin.ATBAPPplugin/0.9")
|
||||
|
||||
|
||||
|
||||
#endif // ATBAPPPLUGIN_H
|
147
plugins/CC/CCDummy.cpp
Normal file
147
plugins/CC/CCDummy.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "CCDummy.h"
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
using namespace nsCCInterface;
|
||||
|
||||
|
||||
const std::string CCInterfacePluginInfoString = R"(
|
||||
{
|
||||
"PluginName": "CCDummy",
|
||||
"Version": "1.0",
|
||||
"git-describe": "",
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
|
||||
CCDummy::CCDummy(QObject *parent) :
|
||||
QObject(parent),
|
||||
errorCode(1),
|
||||
errorDescription(""),
|
||||
pluginState(PLUGIN_STATE::NOT_INITIALIZED)
|
||||
{
|
||||
this->pluginInfo = QString::fromUtf8(CCInterfacePluginInfoString.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
CCDummy::~CCDummy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
PLUGIN_STATE CCDummy::initCCInterfacePlugin(QObject *healthEventReceiver, const QSettings & settings)
|
||||
{
|
||||
Q_UNUSED(healthEventReceiver)
|
||||
|
||||
qDebug() << "called CCDummy::initCalculatePricePlugin()";
|
||||
qDebug() << " pluginName from setting is: " << settings.value("PLUGINS/CCPlugin", "").toString();
|
||||
|
||||
this->pluginState = PLUGIN_STATE::INITIALIZED;
|
||||
|
||||
return this->pluginState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CCDummy::requestReset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCDummy::requestStartTransaction(quint32 amount)
|
||||
{
|
||||
Q_UNUSED(amount)
|
||||
}
|
||||
|
||||
|
||||
void CCDummy::requestCancelTransaction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCDummy::requestRevertTransaction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCDummy::requestConfirmTransaction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCDummy::requestDayClose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCDummy::requestCardInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCDummy::requestPreAuthTransaction(quint32 amount)
|
||||
{
|
||||
Q_UNUSED(amount);
|
||||
}
|
||||
|
||||
void CCDummy::requestCancelPreAuthTransaction(QString & receiptNumber)
|
||||
{
|
||||
Q_UNUSED(receiptNumber);
|
||||
}
|
||||
|
||||
void CCDummy::requestBookTotalTransaction(quint32 amount, QString & receiptNumber)
|
||||
{
|
||||
Q_UNUSED(amount)
|
||||
Q_UNUSED(receiptNumber)
|
||||
}
|
||||
|
||||
void CCDummy::wakeupCC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCDummy::sleepCC()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* Mandatory plugin methods
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
PLUGIN_STATE CCDummy::getState()
|
||||
{
|
||||
return this->pluginState;
|
||||
}
|
||||
|
||||
quint32 CCDummy::getLastError()
|
||||
{
|
||||
return this->errorCode;
|
||||
}
|
||||
|
||||
const QString & CCDummy::getLastErrorDescription()
|
||||
{
|
||||
return this->errorDescription;
|
||||
}
|
||||
|
||||
|
||||
const QString & CCDummy::getPluginInfo()
|
||||
{
|
||||
return pluginInfo;
|
||||
}
|
||||
|
||||
|
||||
|
68
plugins/CC/CCDummy.h
Normal file
68
plugins/CC/CCDummy.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef CCDUMMY_H
|
||||
#define CCDUMMY_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include "CCInterface.h"
|
||||
#include "ATBAPPplugin.h"
|
||||
|
||||
|
||||
class CCDummy : public QObject,
|
||||
public CCInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
Q_INTERFACES(CCInterface)
|
||||
|
||||
public:
|
||||
CCDummy(QObject *parent = 0);
|
||||
~CCDummy();
|
||||
|
||||
// interface:
|
||||
nsCCInterface::PLUGIN_STATE initCCInterfacePlugin(QObject *healthEventReceiver, const QSettings & settings);
|
||||
|
||||
nsCCInterface::PLUGIN_STATE getState();
|
||||
quint32 getLastError();
|
||||
const QString & getLastErrorDescription();
|
||||
|
||||
// return a plugin description in JSON or XML
|
||||
const QString & getPluginInfo();
|
||||
|
||||
|
||||
public slots:
|
||||
void requestReset();
|
||||
void requestStartTransaction(quint32 amount);
|
||||
void requestCancelTransaction();
|
||||
void requestRevertTransaction();
|
||||
void requestConfirmTransaction();
|
||||
void requestDayClose();
|
||||
void requestCardInfo();
|
||||
void requestPreAuthTransaction(quint32 amount);
|
||||
void requestCancelPreAuthTransaction(QString & receiptNumber);
|
||||
void requestBookTotalTransaction(quint32 amount, QString & receiptNumber);
|
||||
|
||||
void wakeupCC();
|
||||
void sleepCC();
|
||||
|
||||
signals:
|
||||
void sendStartTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendCancelTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendRevertTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendConfirmTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendDayCloseResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendCardInfoResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendCancelPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
void sendBookTotalTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result);
|
||||
|
||||
private:
|
||||
quint32 errorCode;
|
||||
QString errorCodeString;
|
||||
QString errorDescription;
|
||||
QString pluginInfo;
|
||||
|
||||
nsCCInterface::PLUGIN_STATE pluginState;
|
||||
|
||||
};
|
||||
|
||||
#endif // CCDUMMY_H
|
86
plugins/CC/CCInterface.h
Normal file
86
plugins/CC/CCInterface.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef CCINTERFACE_H
|
||||
#define CCINTERFACE_H
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
#include "ATBAPPplugin.h"
|
||||
|
||||
|
||||
namespace nsCCInterface {
|
||||
enum class PLUGIN_STATE : quint8;
|
||||
enum class RESULT_STATE : quint8;
|
||||
}
|
||||
|
||||
|
||||
class CCInterface : public ATBAPPplugin
|
||||
{
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
|
||||
public:
|
||||
virtual ~CCInterface() {}
|
||||
|
||||
virtual nsCCInterface::PLUGIN_STATE initCCInterfacePlugin(QObject *healthEventReceiver, const QSettings & settings) = 0;
|
||||
|
||||
|
||||
virtual nsCCInterface::PLUGIN_STATE getState() = 0;
|
||||
virtual quint32 getLastError() = 0;
|
||||
virtual const QString & getLastErrorDescription() = 0;
|
||||
|
||||
// return a plugin description in JSON or XML
|
||||
// -> ATBAPPplugin::getPluginInfo()
|
||||
|
||||
public slots:
|
||||
virtual void requestReset() = 0;
|
||||
virtual void requestStartTransaction(quint32 amount) = 0;
|
||||
virtual void requestCancelTransaction() = 0;
|
||||
virtual void requestRevertTransaction() = 0;
|
||||
virtual void requestConfirmTransaction() = 0;
|
||||
virtual void requestDayClose() = 0;
|
||||
virtual void requestCardInfo() = 0;
|
||||
virtual void requestPreAuthTransaction(quint32 amount) = 0;
|
||||
virtual void requestCancelPreAuthTransaction(QString & receiptNumber) = 0;
|
||||
virtual void requestBookTotalTransaction(quint32 amount, QString & receiptNumber) = 0;
|
||||
virtual void wakeupCC() = 0;
|
||||
virtual void sleepCC() = 0;
|
||||
|
||||
signals:
|
||||
virtual void sendStartTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendCancelTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendRevertTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendConfirmTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendDayCloseResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendCardInfoResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendCancelPreAuthTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
virtual void sendBookTotalTransactionResult(nsCCInterface::RESULT_STATE resultState, QString & result) = 0;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(CCInterface,
|
||||
"eu.atb.ptu.plugin.CCInterface/2.9.1")
|
||||
|
||||
|
||||
namespace nsCCInterface {
|
||||
|
||||
enum class PLUGIN_STATE : quint8 {
|
||||
NOT_INITIALIZED = 0,
|
||||
INITIALIZED = 1
|
||||
};
|
||||
|
||||
enum class RESULT_STATE : quint8 {
|
||||
SUCCESS = 1,
|
||||
ERROR_BACKEND = 2,
|
||||
ERROR_NETWORK = 3,
|
||||
ERROR_TIMEOUT = 4,
|
||||
ERROR_PROCESS = 5,
|
||||
ERROR_BUSY = 6,
|
||||
ERROR_STATE = 7,
|
||||
INFO = 8
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CCINTERFACE_H
|
215
plugins/CalculatePrice/CalculatePriceDefault.cpp
Normal file
215
plugins/CalculatePrice/CalculatePriceDefault.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
#include "CalculatePriceDefault.h"
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
using namespace nsCalculatePriceInterface;
|
||||
|
||||
|
||||
|
||||
const std::string CalculatePriceInterfacePluginInfoString = R"(
|
||||
{
|
||||
"PluginName": "CalculatePriceDummy",
|
||||
"Version": "1.0",
|
||||
"git-describe": "",
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
|
||||
CalculatePriceDefault::CalculatePriceDefault(QObject *parent) :
|
||||
QObject(parent),
|
||||
errorCode(1),
|
||||
errorDescription(""),
|
||||
pluginState(PLUGIN_STATE::NOT_INITIALIZED)
|
||||
{
|
||||
this->pluginInfo = QString::fromUtf8(CalculatePriceInterfacePluginInfoString.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
CalculatePriceDefault::~CalculatePriceDefault()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
PLUGIN_STATE CalculatePriceDefault::initCalculatePricePlugin(QObject *healthEventReceiver, const QSettings & settings)
|
||||
{
|
||||
Q_UNUSED(healthEventReceiver)
|
||||
|
||||
qDebug() << "called CalculatePriceDummy::initCalculatePricePlugin()";
|
||||
qDebug() << " pluginName from setting is: " << settings.value("PLUGINS/CalculatePricePlugin", "").toString();
|
||||
|
||||
this->pluginState = PLUGIN_STATE::INITIALIZED;
|
||||
|
||||
return this->pluginState;
|
||||
}
|
||||
|
||||
|
||||
void CalculatePriceDefault::requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType)
|
||||
{
|
||||
Q_UNUSED(PermitType)
|
||||
|
||||
emit this->requestCalculatePriceResult(RESULT_STATE::SUCCESS,
|
||||
AccessInformation,
|
||||
AccessInformationType,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"1",
|
||||
"dummyPlugin"
|
||||
);
|
||||
}
|
||||
|
||||
void CalculatePriceDefault::requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
const QString & parktime)
|
||||
{
|
||||
Q_UNUSED(PermitType)
|
||||
Q_UNUSED(parktime)
|
||||
|
||||
emit this->requestCalculatePriceResult(RESULT_STATE::SUCCESS,
|
||||
AccessInformation,
|
||||
AccessInformationType,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"1",
|
||||
"dummyPlugin"
|
||||
);
|
||||
}
|
||||
|
||||
void CalculatePriceDefault::requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
nsCalculatePriceInterface::STEP step)
|
||||
{
|
||||
Q_UNUSED(AccessInformation)
|
||||
Q_UNUSED(AccessInformationType)
|
||||
Q_UNUSED(PermitType)
|
||||
Q_UNUSED(step)
|
||||
}
|
||||
|
||||
void CalculatePriceDefault::requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
int coinValue)
|
||||
{
|
||||
Q_UNUSED(AccessInformation)
|
||||
Q_UNUSED(AccessInformationType)
|
||||
Q_UNUSED(PermitType)
|
||||
Q_UNUSED(coinValue)
|
||||
}
|
||||
|
||||
void CalculatePriceDefault::requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
const QString & parktime,
|
||||
const QString & cardInfo,
|
||||
const QString & transactionInfo)
|
||||
{
|
||||
Q_UNUSED(PermitType)
|
||||
Q_UNUSED(parktime)
|
||||
Q_UNUSED(cardInfo)
|
||||
Q_UNUSED(transactionInfo)
|
||||
|
||||
emit this->requestCalculatePriceResult(RESULT_STATE::SUCCESS,
|
||||
AccessInformation,
|
||||
AccessInformationType,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"1",
|
||||
"dummyPlugin"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CalculatePriceDefault::requestProcessTransaction(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString &amount,
|
||||
bool isOffline,
|
||||
const QString & TransactionId,
|
||||
const QString & ReceiptData,
|
||||
const QString & PermitType, const QString &PaymentType)
|
||||
{
|
||||
Q_UNUSED(isOffline)
|
||||
Q_UNUSED(AccessInformation)
|
||||
Q_UNUSED(AccessInformationType)
|
||||
Q_UNUSED(amount)
|
||||
Q_UNUSED(TransactionId)
|
||||
Q_UNUSED(ReceiptData)
|
||||
Q_UNUSED(PermitType)
|
||||
Q_UNUSED(PaymentType)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* Mandatory plugin methods
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
PLUGIN_STATE CalculatePriceDefault::getState()
|
||||
{
|
||||
return this->pluginState;
|
||||
}
|
||||
|
||||
quint32 CalculatePriceDefault::getLastError()
|
||||
{
|
||||
return this->errorCode;
|
||||
}
|
||||
|
||||
const QString & CalculatePriceDefault::getLastErrorDescription()
|
||||
{
|
||||
return this->errorDescription;
|
||||
}
|
||||
|
||||
|
||||
const QString & CalculatePriceDefault::getPluginInfo()
|
||||
{
|
||||
return pluginInfo;
|
||||
}
|
||||
|
||||
|
||||
const QString CalculatePriceDefault::getString(nsCalculatePriceInterface::RESULT_STATE resultState)
|
||||
{
|
||||
QString str;
|
||||
|
||||
switch (resultState) {
|
||||
case nsCalculatePriceInterface::RESULT_STATE::SUCCESS:
|
||||
str = QString("RESULT_STATE::SUCCESS");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::ERROR_BACKEND:
|
||||
str = QString("RESULT_STATE::ERROR_BACKEND");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::ERROR_NETWORK:
|
||||
str = QString("RESULT_STATE::ERROR_NETWORK");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::ERROR_TIMEOUT:
|
||||
str = QString("RESULT_STATE::ERROR_TIMEOUT");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::ERROR_PROCESS:
|
||||
str = QString("RESULT_STATE::ERROR_PROCESS");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::ERROR_RETRY:
|
||||
str = QString("RESULT_STATE::ERROR_RETRY");
|
||||
break;
|
||||
case nsCalculatePriceInterface::RESULT_STATE::INFO:
|
||||
str = QString("RESULT_STATE::INFO");
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
95
plugins/CalculatePrice/CalculatePriceDefault.h
Normal file
95
plugins/CalculatePrice/CalculatePriceDefault.h
Normal file
@ -0,0 +1,95 @@
|
||||
#ifndef CALCULATEPRICEDUMMY_H
|
||||
#define CALCULATEPRICEDUMMY_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include "CalculatePriceInterface.h"
|
||||
using namespace nsCalculatePriceInterface;
|
||||
|
||||
|
||||
class CalculatePriceDefault : public QObject,
|
||||
public CalculatePriceInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CalculatePriceInterface)
|
||||
|
||||
public:
|
||||
CalculatePriceDefault(QObject *parent = 0);
|
||||
~CalculatePriceDefault();
|
||||
|
||||
// interface:
|
||||
PLUGIN_STATE initCalculatePricePlugin(QObject *healthEventReceiver, const QSettings & settings);
|
||||
void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType);
|
||||
void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
const QString & parktime);
|
||||
void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
nsCalculatePriceInterface::STEP step);
|
||||
void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
int coinValue);
|
||||
void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
const QString & parktime,
|
||||
const QString & cardInfo,
|
||||
const QString & transactionInfo);
|
||||
void requestProcessTransaction(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & amount,
|
||||
bool isOffline,
|
||||
const QString & TransactionId,
|
||||
const QString & ReceiptData,
|
||||
const QString & PermitType,
|
||||
const QString & PaymentType);
|
||||
|
||||
|
||||
PLUGIN_STATE getState();
|
||||
quint32 getLastError();
|
||||
const QString & getLastErrorDescription();
|
||||
|
||||
const QString & getPluginInfo();
|
||||
|
||||
const QString getString(nsCalculatePriceInterface::RESULT_STATE resultState);
|
||||
|
||||
signals:
|
||||
void requestCalculatePriceResult(RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const QString & amountDueNet,
|
||||
const QString & amountDueTax,
|
||||
const QString & gracePeriod,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
void requestCalculatePriceResult(RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const PriceInfo & priceInfo,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
void requestProcessTransactionResult(RESULT_STATE resultState,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
|
||||
private:
|
||||
quint32 errorCode;
|
||||
QString errorCodeString;
|
||||
QString errorDescription;
|
||||
QString pluginInfo;
|
||||
|
||||
PLUGIN_STATE pluginState;
|
||||
|
||||
};
|
||||
|
||||
#endif // CALCULATEPRICEDUMMY_H
|
157
plugins/CalculatePrice/CalculatePriceInterface.h
Normal file
157
plugins/CalculatePrice/CalculatePriceInterface.h
Normal file
@ -0,0 +1,157 @@
|
||||
#ifndef CALCULATEPRICEINTERFACE_H
|
||||
#define CALCULATEPRICEINTERFACE_H
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
#include "ATBAPPplugin.h"
|
||||
|
||||
namespace nsCalculatePriceInterface {
|
||||
enum class PLUGIN_STATE : quint8;
|
||||
enum class RESULT_STATE : quint8;
|
||||
enum class STEP : quint8;
|
||||
}
|
||||
|
||||
class PriceInfo
|
||||
{
|
||||
public:
|
||||
int priceNet; // price net in cent
|
||||
int priceTax; // price tax in cent
|
||||
int priceGross; // price gross in cent
|
||||
int taxRate; // tax rate per mill
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CalculatePriceInterface : public ATBAPPplugin
|
||||
{
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
|
||||
public:
|
||||
virtual ~CalculatePriceInterface() {}
|
||||
|
||||
virtual nsCalculatePriceInterface::PLUGIN_STATE initCalculatePricePlugin(QObject *healthEventReceiver,
|
||||
const QSettings & settings) = 0;
|
||||
|
||||
// for price calculation dependent on ID (AccessInformation)
|
||||
virtual void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType) = 0;
|
||||
|
||||
// for price calculation dependent on value (e.g. parking time)
|
||||
virtual void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
const QString & parktime) = 0;
|
||||
|
||||
// for price/time calculation on next step up/down
|
||||
virtual void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
nsCalculatePriceInterface::STEP step) = 0;
|
||||
|
||||
// for price/time calculation on next coin value
|
||||
virtual void requestCalculatePrice(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & PermitType,
|
||||
int coinValue) = 0;
|
||||
|
||||
// for price calculation dependent on additonal values (e.g. parking time, card info, ...)
|
||||
virtual void requestCalculatePrice(const QString & AccessInformation, // primary key e.g. a license plate, credit card number
|
||||
const QString & AccessInformationType, // type of AccessInformation: LICENSEPLATE, CREDITCARD, PIN, ...
|
||||
const QString & PermitType, // e.g. selected product / vehicle
|
||||
const QString & parktime, // parktime in minutes
|
||||
const QString & cardInfo, // additonal card info (e.g. PAN, Institusnummer, Token, ...)
|
||||
const QString & transactionInfo) = 0; // kind of a transcation id, could be used for identification of transaction
|
||||
|
||||
virtual void requestProcessTransaction(const QString & AccessInformation,
|
||||
const QString & AccessInformationType,
|
||||
const QString & amount,
|
||||
bool isOffline,
|
||||
const QString & TransactionId,
|
||||
const QString & ReceiptData,
|
||||
const QString & PermitType,
|
||||
const QString & PaymentType) = 0;
|
||||
|
||||
|
||||
virtual nsCalculatePriceInterface::PLUGIN_STATE getState() = 0;
|
||||
virtual quint32 getLastError() = 0;
|
||||
virtual const QString & getLastErrorDescription() = 0;
|
||||
|
||||
// return a plugin description in JSON or XML
|
||||
// -> ATBAPPplugin::getPluginInfo()
|
||||
|
||||
// helpers e.g. for debug / log
|
||||
virtual const QString getString(nsCalculatePriceInterface::RESULT_STATE resultState) = 0;
|
||||
|
||||
signals:
|
||||
virtual void requestCalculatePriceResult(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const QString & amountDueNet,
|
||||
const QString & amountDueTax,
|
||||
const QString & gracePeriod,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription) = 0;
|
||||
|
||||
virtual void requestCalculatePriceResult(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & accessInformation,
|
||||
const QString & accessInformationType,
|
||||
const QString & amountDuePeriodStart,
|
||||
const QString & amountDuePeriodEnd,
|
||||
const PriceInfo & priceInfo,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription) = 0;
|
||||
|
||||
virtual void requestProcessTransactionResult(nsCalculatePriceInterface::RESULT_STATE resultState,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription) = 0;
|
||||
|
||||
// TODO:
|
||||
/* APPLICATION_PROCESS_TYPE is a global ATB-Type:
|
||||
* - BACKGROUND -> process can work in background without display
|
||||
* - HMI -> display is needed
|
||||
* - t.b.d
|
||||
*
|
||||
* PROCESS_ID is an identifier for e.g. debuging or log which process/module/library/plugin...
|
||||
* caused the prevent
|
||||
*
|
||||
virtual void preventSuspend(APPLICATION_PROCESS_TYPE pt, PROCESS_ID pid) = 0;
|
||||
virtual void allowSuspend(PROCESS_ID pid) = 0;
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
Q_DECLARE_INTERFACE(CalculatePriceInterface,
|
||||
"eu.atb.ptu.plugin.CalculatePriceInterface/4.0")
|
||||
|
||||
|
||||
namespace nsCalculatePriceInterface {
|
||||
|
||||
enum class PLUGIN_STATE : quint8 {
|
||||
NOT_INITIALIZED = 0,
|
||||
INITIALIZED = 1
|
||||
};
|
||||
|
||||
enum class RESULT_STATE : quint8 {
|
||||
SUCCESS = 1, // got price and time from remote
|
||||
ERROR_BACKEND = 2, // error from backand (e.g. backend replies with error)
|
||||
ERROR_NETWORK = 3, // error from network (e.g. host not available)
|
||||
ERROR_TIMEOUT = 4, // the operation timed out
|
||||
ERROR_PROCESS = 5, // internal plugin error (e.g. bug in implementation)
|
||||
ERROR_RETRY = 6, // retry operation
|
||||
INFO = 7
|
||||
};
|
||||
|
||||
enum class STEP : quint8 {
|
||||
UP = 1,
|
||||
DOWN = 2
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // CALCULATEPRICEINTERFACE_H
|
134
plugins/PluginManager.cpp
Normal file
134
plugins/PluginManager.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include <QPluginLoader>
|
||||
#include <QSettings>
|
||||
|
||||
#include "PluginManager.h"
|
||||
#include "ATBHMIconfig.h"
|
||||
|
||||
#include "plugins/ATBAPPplugin.h"
|
||||
#include "plugins/CC/CCInterface.h"
|
||||
#include "plugins/CalculatePrice/CalculatePriceInterface.h"
|
||||
|
||||
|
||||
PluginManager::PluginManager(ATBHMIconfig *config, QObject *parent) :
|
||||
QObject(parent),
|
||||
config(config)
|
||||
{
|
||||
this->loadPlugins();
|
||||
}
|
||||
|
||||
|
||||
void PluginManager::loadPlugins()
|
||||
{
|
||||
/* NOTE: setting a search path via 'QCoreApplication::addLibraryPath' does not work for
|
||||
* user specific plugins...
|
||||
* This seems to work only for QT core plugins which are loaded before QApplication object is
|
||||
* created.
|
||||
* => we set the path for our plugins manually here.
|
||||
*/
|
||||
// DEBUG
|
||||
/* qDebug() << "--------------------------- DEBUG -----------------------------------";
|
||||
* qDebug() << "QCoreApplication::applicationDirPath() = " << QCoreApplication::applicationDirPath();
|
||||
* qDebug() << " ";
|
||||
* qDebug() << "QCoreApplication::libraryPaths()";
|
||||
* foreach (const QString &path, QCoreApplication::libraryPaths()) {
|
||||
* qDebug() << " " << path;
|
||||
* }
|
||||
* qDebug() << "---------------------------------------------------------------------";
|
||||
*/
|
||||
/* NOTE: qputenv() to set LD_LIBRARY_PATH does not work either!
|
||||
* We tried this to set the path were libraries used by the plugin itself could be found
|
||||
* (e.g. kdsoap-library, which is used by several plugins).
|
||||
*/
|
||||
|
||||
// load all available plugins in config group [PLUGINS]
|
||||
QSettings * settings = this->config->getSettingsPtr();
|
||||
|
||||
if (!settings->childGroups().contains("PLUGINS")) {
|
||||
qCritical() << "PluginManager: no plugins defined in config";
|
||||
return;
|
||||
}
|
||||
settings->beginGroup("PLUGINS");
|
||||
QStringList pluginStringList = settings->childKeys();
|
||||
|
||||
QStringListIterator PluginsIterator(pluginStringList);
|
||||
QString pluginKey;
|
||||
QString pluginName;
|
||||
while(PluginsIterator.hasNext()) {
|
||||
pluginKey = PluginsIterator.next();
|
||||
pluginName = settings->value(pluginKey, "").toString();
|
||||
|
||||
if (pluginName == "") {
|
||||
qCritical() << "PluginManager: plugin " << pluginKey << " is not defined";
|
||||
}
|
||||
else if (pluginKey.startsWith('#')) {
|
||||
qCritical() << "PluginManager: skip comment " << pluginKey;
|
||||
}
|
||||
else if (QString::compare(pluginName, "notUsed", Qt::CaseInsensitive) == 0) {
|
||||
qCritical() << "PluginManager: plugin " << pluginKey << " is not used";
|
||||
}
|
||||
else {
|
||||
if (!QLibrary::isLibrary(pluginName)) pluginName.append(".so");
|
||||
if (!pluginName.startsWith("lib")) pluginName.prepend("lib");
|
||||
if (!pluginName.startsWith("plugins")) pluginName.prepend("plugins/");
|
||||
|
||||
if (!pluginName.startsWith('/')) {
|
||||
pluginName.prepend('/').prepend(QApplication::applicationDirPath());
|
||||
}
|
||||
|
||||
qCritical() << "PluginManager::loadPlugins() load plugin: "
|
||||
<< pluginName;
|
||||
|
||||
// TODO: check, if plugin file is available, readable etc...
|
||||
|
||||
QPluginLoader* pluginLoader = new QPluginLoader();
|
||||
pluginLoader->setFileName(pluginName);
|
||||
|
||||
plugins.insert(pluginKey, pluginLoader);
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QObject * PluginManager::getInstance(const QString & pluginname)
|
||||
{
|
||||
QObject * result = nullptr;
|
||||
|
||||
QPluginLoader* pluginLoader = plugins[pluginname];
|
||||
|
||||
if (pluginLoader != nullptr) {
|
||||
|
||||
QObject* plugin = pluginLoader->instance();
|
||||
if (!pluginLoader->isLoaded()) {
|
||||
qCritical() << "PluginManager::getInstance("
|
||||
<< pluginname
|
||||
<< ") errorString: "
|
||||
<< pluginLoader->errorString();
|
||||
}
|
||||
else {
|
||||
result = plugin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const QList<QString> PluginManager::listAvailablePlugins()
|
||||
{
|
||||
return plugins.keys();
|
||||
}
|
||||
|
||||
|
||||
bool PluginManager::isPluginAvailable(const QString & pluginname)
|
||||
{
|
||||
if (plugins[pluginname] != nullptr) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
42
plugins/PluginManager.h
Normal file
42
plugins/PluginManager.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef PLUGINMANAGER_H
|
||||
#define PLUGINMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDir>
|
||||
#include <QHash>
|
||||
|
||||
|
||||
class ATBHMIconfig;
|
||||
class QPluginLoader;
|
||||
|
||||
|
||||
|
||||
class PluginManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PluginManager(ATBHMIconfig *config, QObject *parent = nullptr);
|
||||
|
||||
QObject * getInstance(const QString & pluginname);
|
||||
|
||||
const QList<QString> listAvailablePlugins();
|
||||
bool isPluginAvailable(const QString & pluginname);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
ATBHMIconfig *config;
|
||||
|
||||
QDir pluginsDir;
|
||||
|
||||
void loadPlugins();
|
||||
|
||||
// Hash to store all plugins
|
||||
QHash<QString, QPluginLoader*> plugins;
|
||||
|
||||
};
|
||||
|
||||
#endif // PLUGINMANAGER_H
|
17
src/ATBAPP/ATBAPPplugin.h
Normal file
17
src/ATBAPP/ATBAPPplugin.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef ATBAPPPLUGIN_H
|
||||
#define ATBAPPPLUGIN_H
|
||||
|
||||
/***********************************************************
|
||||
* a simple class with only one method for plugin info
|
||||
*/
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class ATBAPPplugin {
|
||||
public:
|
||||
virtual const QString & getPluginInfo() = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(ATBAPPplugin, "eu.atb.ptu.plugin.ATBAPPplugin/0.9")
|
||||
|
||||
#endif // ATBAPPPLUGIN_H
|
91
src/ATBAPP/ATBVMCPlugin.cpp
Normal file
91
src/ATBAPP/ATBVMCPlugin.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "src/ATBAPP/ATBVMCPlugin.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QPluginLoader>
|
||||
#include <QDateTime>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QUuid>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
ATBVMCPlugin::ATBVMCPlugin(QObject *parent)
|
||||
: m_errorCode("")
|
||||
, m_errorDescription("")
|
||||
, m_pluginInfo("")
|
||||
, m_serialPortName("")
|
||||
, m_useDebug(false)
|
||||
, m_pluginState(PLUGIN_STATE::NOT_INITIALIZED)
|
||||
, m_eventReceiver(nullptr) {
|
||||
this->setParent(parent);
|
||||
}
|
||||
|
||||
ATBVMCPlugin::~ATBVMCPlugin() {
|
||||
}
|
||||
|
||||
PLUGIN_STATE ATBVMCPlugin::initVMCPlugin(QObject *eventReceiver,
|
||||
QSettings const &settings) {
|
||||
Q_UNUSED(eventReceiver);
|
||||
Q_UNUSED(settings);
|
||||
return PLUGIN_STATE::NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
// mandantory ATBAPP plugin methods: ------------------------------------------
|
||||
PLUGIN_STATE ATBVMCPlugin::getState() {
|
||||
return PLUGIN_STATE::NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
QString ATBVMCPlugin::getLastError() {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ATBVMCPlugin::getLastErrorDescription() {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString const &ATBVMCPlugin::getPluginInfo() {
|
||||
static QString info;
|
||||
return info;
|
||||
}
|
||||
|
||||
// helpers e.g. for debug / log
|
||||
QString ATBVMCPlugin::getString(RESULT_STATE /*resultState*/) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::onChangedProgramModeToSELL() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::onChangedProgramModeToSERVICE() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::onChangedProgramModeToIDLE() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::onChangedProgramModeToOOO() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::startPhysicalLayer() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::stopPhysicalLayer() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::reboot() {
|
||||
|
||||
}
|
||||
|
||||
void ATBVMCPlugin::reset() {
|
||||
|
||||
}
|
61
src/ATBAPP/ATBVMCPlugin.h
Normal file
61
src/ATBAPP/ATBVMCPlugin.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef ATBVMCPLUGIN_H
|
||||
#define ATBVMCPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "src/ATBAPP/VMCInterface.h"
|
||||
#include "src/ATBAPP/ATBAPPplugin.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "include/interfaces.h"
|
||||
|
||||
|
||||
class ATBVMCPlugin : public VMCInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
Q_INTERFACES(UnifiedDCVMCInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA( IID "ATBVMCPlugin" )
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit ATBVMCPlugin(QObject *parent = nullptr);
|
||||
~ATBVMCPlugin();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// interface:
|
||||
PLUGIN_STATE initVMCPlugin(QObject *eventReceiver, QSettings const &settings);
|
||||
|
||||
// mandantory ATBAPP plugin methods: ------------------------------------------
|
||||
PLUGIN_STATE getState() override;
|
||||
QString getLastError() override;
|
||||
QString getLastErrorDescription() override;
|
||||
|
||||
virtual const QString & getPluginInfo() override;
|
||||
|
||||
// helpers e.g. for debug / log
|
||||
virtual QString getString(RESULT_STATE resultState) override;
|
||||
|
||||
public slots:
|
||||
virtual void onChangedProgramModeToSELL() override;
|
||||
virtual void onChangedProgramModeToSERVICE() override;
|
||||
virtual void onChangedProgramModeToIDLE() override;
|
||||
virtual void onChangedProgramModeToOOO() override;
|
||||
|
||||
virtual void startPhysicalLayer() override;
|
||||
virtual void stopPhysicalLayer() override;
|
||||
virtual void reboot() override;
|
||||
virtual void reset() override;
|
||||
|
||||
private:
|
||||
QString m_errorCode;
|
||||
QString m_errorDescription;
|
||||
QString m_pluginInfo;
|
||||
QString m_serialPortName;
|
||||
bool m_useDebug;
|
||||
PLUGIN_STATE m_pluginState;
|
||||
QObject* m_eventReceiver;
|
||||
};
|
||||
|
||||
#endif // ATBDEVICECONTROLLERPLUGIN_H
|
143
src/ATBAPP/UnifiedDCVMCInterface.h
Normal file
143
src/ATBAPP/UnifiedDCVMCInterface.h
Normal file
@ -0,0 +1,143 @@
|
||||
#ifndef UNIFIED_DCVMC_INTERFACE_H_INCLUDED
|
||||
#define UNIFIED_DCVMC_INTERFACE_H_INCLUDED
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
#include "ATBAPPplugin.h"
|
||||
|
||||
class UnifiedDCVMCInterface : public QObject, public ATBAPPplugin {
|
||||
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
|
||||
public:
|
||||
enum class PLUGIN_STATE : quint8 {
|
||||
NOT_INITIALIZED = 0,
|
||||
INITIALIZED = 1
|
||||
};
|
||||
enum class RESULT_STATE : quint8 {
|
||||
SUCCESS = 1, // operation was successfull
|
||||
ERROR_BACKEND, // error from backend (e.g. backend replies with error)
|
||||
ERROR_TIMEOUT, // the operation timed out
|
||||
ERROR_PROCESS, // internal plugin error, should not occur (this is a bug in implementation)
|
||||
ERROR_RETRY, // retry operation
|
||||
INFO // informational (e.g. display a message, log something etc.)
|
||||
};
|
||||
enum class CASH_STATE : quint8 {
|
||||
CACHE_EMPTY, // Cache still empty, default state
|
||||
CACHE_INPUT, // Coins are in Cache
|
||||
OVERPAYED,
|
||||
/* t.b.d. */
|
||||
};
|
||||
enum class TICKET_VARIANT : quint8 {
|
||||
PARKING_TICKET,
|
||||
RECEIPT,
|
||||
ERROR_RECEIPT,
|
||||
START_RECEIPT, // e.g. Szeged Start
|
||||
STOP_RECEIPT, // e.g. Szeged Stop
|
||||
};
|
||||
|
||||
explicit UnifiedDCVMCInterface() = default;
|
||||
virtual ~UnifiedDCVMCInterface() {}
|
||||
|
||||
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver, QSettings const &settings) = 0;
|
||||
|
||||
// mandantory ATBAPP plugin methods:
|
||||
virtual PLUGIN_STATE getState() = 0;
|
||||
virtual QString getLastError() = 0;
|
||||
virtual QString getLastErrorDescription() = 0;
|
||||
|
||||
virtual QString getString(RESULT_STATE resultState) = 0;
|
||||
|
||||
public slots:
|
||||
virtual void onChangedProgramModeToSELL() = 0;
|
||||
virtual void onChangedProgramModeToSERVICE() = 0;
|
||||
virtual void onChangedProgramModeToIDLE() = 0;
|
||||
virtual void onChangedProgramModeToOOO() = 0;
|
||||
|
||||
virtual void startPhysicalLayer() = 0;
|
||||
virtual void stopPhysicalLayer() = 0;
|
||||
virtual void reboot() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
signals:
|
||||
void printTicketFinished(RESULT_STATE resultState,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
void printReceiptFinished(RESULT_STATE resultState,
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
/**
|
||||
* emitted on e.g. a coin input
|
||||
*/
|
||||
void cashInputEvent(RESULT_STATE resultState,
|
||||
CASH_STATE cashState,
|
||||
const QString & newCashValue,
|
||||
/* additional variables? */
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
/**
|
||||
* emitted if cashInput has been stopped, e.g. in result to task requestStopCashInput():
|
||||
* -> shutter is blocked
|
||||
* -> no cash input is possible
|
||||
* -> coins are in cache
|
||||
*/
|
||||
void cashInputFinished(RESULT_STATE resultState,
|
||||
const QString & newCashValue,
|
||||
/* additional variables? */
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
|
||||
/**
|
||||
* emitted e.g. if service door is opened
|
||||
*/
|
||||
void requestModeSERVICE();
|
||||
|
||||
/**
|
||||
* emitted e.g. if doors are closed
|
||||
*/
|
||||
void requestModeIDLE();
|
||||
|
||||
/**
|
||||
* emitted e.g. on severe errors
|
||||
*/
|
||||
void requestModeOOO();
|
||||
|
||||
/**
|
||||
* emitted e.g. if service door is opened
|
||||
*/
|
||||
void requestAccountResponse(const QHash<QString, QVariant> & accountData);
|
||||
|
||||
/**
|
||||
* emitted on error
|
||||
* depending on errorCode:
|
||||
* -> interrupt selling process
|
||||
* -> machine can go to state OOO
|
||||
* -> send error event to ISMAS
|
||||
* -> ...
|
||||
*/
|
||||
void Error(
|
||||
/* additional variables? */
|
||||
const QString & errorCode,
|
||||
const QString & errorDescription);
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(UnifiedDCVMCInterface,
|
||||
"eu.atb.ptu.plugin.UnifiedDCVMCInterface/1.0")
|
||||
|
||||
using PLUGIN_STATE = UnifiedDCVMCInterface::PLUGIN_STATE;
|
||||
using RESULT_STATE = UnifiedDCVMCInterface::RESULT_STATE;
|
||||
using CASH_STATE = UnifiedDCVMCInterface::CASH_STATE;
|
||||
using TICKET_VARIANT = UnifiedDCVMCInterface::TICKET_VARIANT;
|
||||
|
||||
#endif // UNIFIED_DCVMC_INTERFACE_H_INCLUDED
|
42
src/ATBAPP/VMCInterface.h
Normal file
42
src/ATBAPP/VMCInterface.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef VMCINTERFACE_H
|
||||
#define VMCINTERFACE_H
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
#include "ATBAPPplugin.h"
|
||||
#include "UnifiedDCVMCInterface.h"
|
||||
|
||||
namespace nsVMCInterface {
|
||||
using PLUGIN_STATE = UnifiedDCVMCInterface::PLUGIN_STATE;
|
||||
using RESULT_STATE = UnifiedDCVMCInterface::RESULT_STATE;
|
||||
using CASH_STATE = UnifiedDCVMCInterface::CASH_STATE;
|
||||
using TICKET_VARIANT = UnifiedDCVMCInterface::TICKET_VARIANT;
|
||||
}
|
||||
|
||||
class VMCInterface : public UnifiedDCVMCInterface {
|
||||
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(ATBAPPplugin)
|
||||
Q_INTERFACES(UnifiedDCVMCInterface)
|
||||
|
||||
public:
|
||||
|
||||
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver, QSettings const &settings) override {
|
||||
return initVMCPlugin(eventReceiver, settings);
|
||||
}
|
||||
|
||||
virtual ~VMCInterface() {}
|
||||
|
||||
/**
|
||||
* @brief initDCPlugin
|
||||
* @param eventReceiver - QObject to receive ATBMachineEvents or HealthEvents
|
||||
* @param settings
|
||||
* @return
|
||||
*/
|
||||
virtual PLUGIN_STATE initVMCPlugin(QObject *eventReceiver, const QSettings & settings) = 0;
|
||||
};
|
||||
|
||||
#endif // VMCINTERFACE_H
|
244
src/ATBAPP/support/VMC/ReceiveBuffer.cpp
Normal file
244
src/ATBAPP/support/VMC/ReceiveBuffer.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
#include <QTimer>
|
||||
#include "ReceiveBuffer.h"
|
||||
#include "vmc.h"
|
||||
#include <QDebug>
|
||||
|
||||
ReceiveBuffer::ReceiveBuffer(COM_interface *cinterface, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<RECEIVE_ERROR>("RECEIVE_ERROR");
|
||||
this->vmc = (VMC*)parent;
|
||||
this->interface = cinterface;
|
||||
|
||||
connect(interface, SIGNAL(ReadData(QByteArray*)), this, SLOT(getData(QByteArray*)));
|
||||
connect(vmc, SIGNAL(CommandProcessed()), this, SLOT(removeCommand()));
|
||||
connect(this, SIGNAL(CommandAvailiable(QByteArray)), vmc, SLOT(CommandAvaliable(QByteArray)));
|
||||
|
||||
currentMessage.clear();
|
||||
|
||||
receiveIdleTimer = new QTimer(this);
|
||||
receiveIdleTimer->setInterval(2000); // clear possible wrong data in receive buffer after 2s
|
||||
receiveIdleTimer->setSingleShot(false);
|
||||
|
||||
connect(receiveIdleTimer, SIGNAL(timeout()), this, SLOT(onReceiveIdleTimerTimeout()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
ReceiveBuffer::~ReceiveBuffer()
|
||||
{
|
||||
delete(this->receiveIdleTimer);
|
||||
}
|
||||
|
||||
|
||||
int ReceiveBuffer::size()
|
||||
{
|
||||
return messageQueue.size();
|
||||
}
|
||||
|
||||
|
||||
void ReceiveBuffer::removeCommand()
|
||||
{
|
||||
if (messageQueue.size() > 0) {
|
||||
messageQueue.removeFirst();
|
||||
}
|
||||
else {
|
||||
qDebug() << "ReceiveBuffer::removeCommand(): no message to remove!";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReceiveBuffer::onReceiveIdleTimerTimeout()
|
||||
{
|
||||
this->currentMessage.clear();
|
||||
this->receiveIdleTimer->stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ReceiveBuffer::getData(QByteArray *data)
|
||||
{
|
||||
int CRCindex;
|
||||
int COMMAND_IN_PROGRESS = 1;
|
||||
|
||||
// do nothing, if there is no data
|
||||
if (data->size() == 0) { return; }
|
||||
|
||||
// DEBUG
|
||||
/*
|
||||
qDebug() << "ReceiveBuffer::getData(): messageQueue.size = " << messageQueue.size();
|
||||
qDebug() << "ReceiveBuffer::getData(): data = " << data;
|
||||
qDebug() << "ReceiveBuffer::getData(): data->size() = " << data->size();
|
||||
qDebug() << "ReceiveBuffer::getData(): ¤tMessage = " << ¤tMessage;
|
||||
qDebug() << "ReceiveBuffer::getData(): currentMessage.capacity = " << currentMessage.capacity();
|
||||
qDebug() << "ReceiveBuffer::getData(): currentMessage.size() = " << currentMessage.size();
|
||||
*/
|
||||
|
||||
this->receiveIdleTimer->start();
|
||||
|
||||
// for safety: prevent currentMessage to grow infinitely in size.
|
||||
if (currentMessage.size() > 0xFF) {
|
||||
emit ReceiveError(RECEIVE_ERROR::INVALID_COMMAND);
|
||||
currentMessage.clear();
|
||||
}
|
||||
|
||||
|
||||
// we use append because data can be an interrupted command:
|
||||
currentMessage.append(data->data(), data->size());
|
||||
|
||||
//qDebug() << "ReceiveBuffer::getData(): currentMessage = " << QString(currentMessage);
|
||||
|
||||
|
||||
// process commands:
|
||||
while (COMMAND_IN_PROGRESS) {
|
||||
|
||||
int startindex = currentMessage.indexOf(0x3e); // find start of command
|
||||
|
||||
// detect ACK/NACK response messages from vmc:
|
||||
if (startindex != 0) {
|
||||
int forEnd = -1;
|
||||
if (startindex > 0) forEnd = startindex; // if ACK/NACK is before command ...
|
||||
if (startindex == -1) forEnd = currentMessage.size(); // if ACK/NACK is the only data
|
||||
|
||||
for (int i = 0; i != forEnd; i++) {
|
||||
switch (currentMessage.at(i)) {
|
||||
case ACK: emit ReceiveResponse(ACK);
|
||||
break;
|
||||
case NACK: emit ReceiveResponse(NACK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(startindex == -1) {
|
||||
currentMessage.clear();
|
||||
COMMAND_IN_PROGRESS = 0;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
currentMessage.remove(0,startindex);
|
||||
}
|
||||
|
||||
// now, we have at least a beginning message
|
||||
CRCindex = checkMessageForCRC();
|
||||
|
||||
if (CRCindex == 0) {
|
||||
// exit this methode and message part is still in currentMessage.
|
||||
break;
|
||||
}
|
||||
if (CRCindex < 0) {
|
||||
|
||||
//qCriticalBAMessage(currentMessage);
|
||||
|
||||
emit ReceiveError(RECEIVE_ERROR::INVALID_COMMAND);
|
||||
currentMessage.clear();
|
||||
COMMAND_IN_PROGRESS = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//qDebug() << "ReceiveBuffer::getData(): startindex = " << startindex;
|
||||
//qDebug() << "ReceiveBuffer::getData(): currentMessage = " << currentMessage;
|
||||
//qDebug() << "ReceiveBuffer::getData(): CRCindex = " << CRCindex;
|
||||
|
||||
if (CRCindex) {
|
||||
// found a complete message
|
||||
if (checkCRC(currentMessage.at(CRCindex), CRCindex)) {
|
||||
messageQueue << currentMessage.left(CRCindex + 1);
|
||||
emit CommandAvailiable(messageQueue.first());
|
||||
}
|
||||
else {
|
||||
emit ReceiveError(RECEIVE_ERROR::CRC);
|
||||
}
|
||||
|
||||
if (currentMessage.size() > (CRCindex + 1)) {
|
||||
currentMessage.remove(0,(CRCindex + 1));
|
||||
}
|
||||
else {
|
||||
currentMessage.clear();
|
||||
COMMAND_IN_PROGRESS = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ReceiveBuffer::checkMessageForCRC()
|
||||
{
|
||||
int CRCindex;
|
||||
int DataLengthIndex;
|
||||
|
||||
|
||||
// qDebug() << "ReceiveBuffer::checkMessageForCRC(): currentMessage.size = " << currentMessage.size();
|
||||
// for (int i = 0; i < currentMessage.size(); i++)
|
||||
// qDebug() << " currentMessage.at(" << i << ") = " << currentMessage.at(i);
|
||||
|
||||
|
||||
if (currentMessage.size() <= 1)
|
||||
return 0;
|
||||
|
||||
switch (currentMessage.at(1)) {
|
||||
case 0x60: DataLengthIndex = 5; break;
|
||||
case 0x61: DataLengthIndex = 6; break;
|
||||
default: DataLengthIndex = 2; break;
|
||||
}
|
||||
|
||||
if (currentMessage.size() <= DataLengthIndex)
|
||||
return 0;
|
||||
|
||||
if (( (static_cast<quint8>(currentMessage.at(DataLengthIndex)) - 0x30)) <= 0 )
|
||||
return -1;
|
||||
|
||||
CRCindex = DataLengthIndex + ( static_cast<quint8>(currentMessage.at(DataLengthIndex)) - 0x30) + 1;
|
||||
|
||||
if (currentMessage.size() <= CRCindex)
|
||||
return 0;
|
||||
else
|
||||
return CRCindex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ReceiveBuffer::checkCRC(quint8 CRC, int index)
|
||||
{
|
||||
quint8 cCRC = 0;
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
cCRC += static_cast<quint8>(currentMessage.at(i));
|
||||
//qDebug() << "ReceiveBuffer::checkCRC(): currentMessage.at(i) = " << currentMessage.at(i);
|
||||
}
|
||||
|
||||
//qDebug() << "ReceiveBuffer::checkCRC(): cCRC = " << cCRC;
|
||||
//qDebug() << "ReceiveBuffer::checkCRC(): CRC = " << CRC;
|
||||
|
||||
|
||||
if (cCRC == CRC) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief ReceiveBuffer::qCriticalBAMessage
|
||||
* @param message
|
||||
*
|
||||
* This is for test and debugging only.
|
||||
*/
|
||||
void ReceiveBuffer::qCriticalBAMessage(QByteArray message)
|
||||
{
|
||||
QString hexString = "received: ";
|
||||
qint64 i;
|
||||
|
||||
for (i=0; i < message.size(); i++) {
|
||||
hexString.append((QString(message.at(i))).toLatin1().toHex());
|
||||
hexString.append(' ');
|
||||
}
|
||||
hexString.chop(1);
|
||||
|
||||
//qCritical() << "VMC::CommandAvaliable(): message.size(): " << message.size() << "";
|
||||
qCritical() << "VMC::qCriticalBAMessage(): message: " << hexString << "";
|
||||
|
||||
}
|
||||
|
||||
|
72
src/ATBAPP/support/VMC/ReceiveBuffer.h
Normal file
72
src/ATBAPP/support/VMC/ReceiveBuffer.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef RECEIVEBUFFER_H
|
||||
#define RECEIVEBUFFER_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include "com_interface.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class QTimer;
|
||||
class VMC;
|
||||
enum class RECEIVE_ERROR : quint8;
|
||||
|
||||
|
||||
class ReceiveBuffer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
private:
|
||||
VMC *vmc;
|
||||
COM_interface *interface;
|
||||
|
||||
QList<QByteArray> messageQueue;
|
||||
QByteArray currentMessage;
|
||||
|
||||
int checkMessageForCRC();
|
||||
bool checkCRC(quint8 CRC, int index);
|
||||
|
||||
/* the receiveIdleTimer clears the receive buffer (currentMessag), if for
|
||||
* a certain time no data was received.
|
||||
* This is for improve speed for responding on vmc messages because possible
|
||||
* wrong data is removed from queue.
|
||||
*/
|
||||
QTimer *receiveIdleTimer;
|
||||
|
||||
// for debug:
|
||||
void qCriticalBAMessage(QByteArray message);
|
||||
|
||||
public:
|
||||
explicit ReceiveBuffer(COM_interface *cinterface, QObject *parent = nullptr);
|
||||
~ReceiveBuffer();
|
||||
|
||||
int size();
|
||||
|
||||
|
||||
signals:
|
||||
void CommandAvailiable(QByteArray command);
|
||||
void ReceiveError(RECEIVE_ERROR error);
|
||||
void ReceiveResponse(quint8 response);
|
||||
|
||||
|
||||
private slots:
|
||||
void removeCommand();
|
||||
void getData(QByteArray *data);
|
||||
|
||||
void onReceiveIdleTimerTimeout();
|
||||
|
||||
};
|
||||
|
||||
|
||||
enum class RECEIVE_ERROR : quint8 {
|
||||
NO_ERROR = 0,
|
||||
CRC,
|
||||
NO_COMMAND,
|
||||
INVALID_COMMAND
|
||||
};
|
||||
|
||||
#endif // RECEIVEBUFFER_H
|
206
src/ATBAPP/support/VMC/SendBuffer.cpp
Normal file
206
src/ATBAPP/support/VMC/SendBuffer.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
#include <QTimer>
|
||||
#include "SendBuffer.h"
|
||||
#include "vmc.h"
|
||||
#include <QDebug>
|
||||
#include "version.h"
|
||||
|
||||
SendBuffer::SendBuffer(COM_interface *cinterface, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<SEND_ERROR>("SEND_ERROR");
|
||||
this->vmc = (VMC*)parent;
|
||||
this->interface = cinterface;
|
||||
|
||||
this->responseTimeoutTimer = new QTimer(this);
|
||||
this->responseTimeoutTimer->setInterval(1000); // resend message to vmc after 1s without response
|
||||
this->responseTimeoutTimer->setSingleShot(false);
|
||||
|
||||
connect(this->responseTimeoutTimer, SIGNAL(timeout()), this, SLOT(onResponseTimeoutTimerTimeout()));
|
||||
responseTimerTimeoutCounter = 0;
|
||||
|
||||
resendCounter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
SendBuffer::~SendBuffer()
|
||||
{
|
||||
delete(this->responseTimeoutTimer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* public interface
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
/**
|
||||
* from vmc: sendMessage / insert Message in Message-Queue
|
||||
*
|
||||
* interactiveFlag: (default = true)
|
||||
* Interactive commands are commands resulting from user input (e.g. button clicks).
|
||||
* This commands are enqueued only if responseTimeoutTimer is not active.
|
||||
* This ensures, that such messages are sent in sequence and only, if an answer
|
||||
* from vmc was received.
|
||||
* Non-interactive commands are data messages which are sent to vmc, caused e.g. by
|
||||
* an internal status change.
|
||||
*
|
||||
*/
|
||||
int SendBuffer::SendMessage(QByteArray & ba, bool enqueue)
|
||||
{
|
||||
|
||||
// prevent queue for growing endlessly:
|
||||
|
||||
// check size of queue
|
||||
// if queue-size is greater than SB_MAX_SENDQUEUESIZE, remove oldest (first) element
|
||||
|
||||
qDebug() << "SendBuffer::SendMessage() messageQueue.size() = " << this->messageQueue.size();
|
||||
|
||||
if (this->messageQueue.size() > SB_MAX_SENDQUEUESIZE) {
|
||||
messageQueue.removeFirst();
|
||||
this->resendCounter = 0;
|
||||
}
|
||||
|
||||
// put message in queue
|
||||
if (enqueue)
|
||||
this->messageQueue.enqueue(ba);
|
||||
|
||||
|
||||
/* interactive messages are sent only, if the response timer is not active.
|
||||
* this should prevent successive sending of the same message during waiting
|
||||
* for an answer from vmc.
|
||||
*/
|
||||
if (! this->responseTimeoutTimer->isActive()) {
|
||||
|
||||
if(!enqueue)
|
||||
this->messageQueue.enqueue(ba);
|
||||
|
||||
// try to send message
|
||||
this->PrivateSendMessage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* private interface
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* handle ACK/NACK response from vmc
|
||||
*
|
||||
*/
|
||||
void SendBuffer::onReceiveResponse(quint8 response)
|
||||
{
|
||||
if (this->messageQueue.size() == 0) return;
|
||||
|
||||
// reset counter:
|
||||
this->responseTimerTimeoutCounter = 0;
|
||||
|
||||
//if (response == NACK) qDebug() << "onReceiveResponse() NACK";
|
||||
//if (response == ACK) qDebug() << "onReceiveResponse() ACK";
|
||||
qDebug() << "--- onReceiveResponse() messageQueue.size() = " << this->messageQueue.size();
|
||||
|
||||
|
||||
|
||||
/* resend command on NACK */
|
||||
if (response == NACK) {
|
||||
|
||||
// stop timeoutTimer
|
||||
this->responseTimeoutTimer->stop();
|
||||
|
||||
if (this->resendCounter > SB_MAX_RESEND) {
|
||||
// command could not be processed on peer: remove it from message queue
|
||||
this->messageQueue.removeFirst();
|
||||
this->resendCounter = 0;
|
||||
}
|
||||
else {
|
||||
// else: resend command
|
||||
if (this->messageQueue.size() != 0) this->PrivateSendMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* send next command on ACK */
|
||||
if (response == ACK) {
|
||||
|
||||
// stop timeoutTimer
|
||||
this->responseTimeoutTimer->stop();
|
||||
|
||||
// remove old message from message-queue
|
||||
this->messageQueue.removeFirst();
|
||||
this->resendCounter = 0;
|
||||
|
||||
if (this->messageQueue.size() != 0) this->PrivateSendMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* this timeout-handler is called, if no response (ACK/NACK) was received from vmc
|
||||
*/
|
||||
void SendBuffer::onResponseTimeoutTimerTimeout()
|
||||
{
|
||||
|
||||
qDebug() << "onResponseTimeoutTimerTimeout() messageQueue.size() = " << this->messageQueue.size();
|
||||
|
||||
if (this->messageQueue.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// wakeup vmc
|
||||
emit this->sendError(SEND_ERROR::RESPONSE);
|
||||
|
||||
if (this->resendCounter > SB_MAX_RESEND) {
|
||||
this->messageQueue.removeFirst();
|
||||
this->resendCounter = 0;
|
||||
this->responseTimerTimeoutCounter++;
|
||||
this->responseTimeoutTimer->stop();
|
||||
emit this->sendError(SEND_ERROR::RESPONSE_TIMER_TIMEOUT);
|
||||
if (this->responseTimerTimeoutCounter > 10) {
|
||||
// switch to self out-of-order mode ...
|
||||
emit this->sendError(SEND_ERROR::MULTIPLE_RESPONSE_TIMER_TIMEOUT);
|
||||
}
|
||||
// try to send an possible next message in order
|
||||
// to empty queue:
|
||||
if (!this->messageQueue.isEmpty()) {
|
||||
PrivateSendMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// send next message
|
||||
else {
|
||||
PrivateSendMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* send first message in Message-Queue
|
||||
*
|
||||
* preconditon: at least one message is in queue!
|
||||
*/
|
||||
void SendBuffer::PrivateSendMessage()
|
||||
{
|
||||
// take message from queue
|
||||
QByteArray ba = this->messageQueue.head();
|
||||
|
||||
|
||||
// put bytes on serial line
|
||||
for (int i = 0; i < ba.size(); i++) {
|
||||
this->interface->putChar(ba.at(i));
|
||||
}
|
||||
|
||||
// do logging here
|
||||
emit this->writeLogSent(ba);
|
||||
|
||||
|
||||
this->resendCounter++;
|
||||
|
||||
// start timeoutTimer
|
||||
this->responseTimeoutTimer->start();
|
||||
|
||||
|
||||
}
|
59
src/ATBAPP/support/VMC/SendBuffer.h
Normal file
59
src/ATBAPP/support/VMC/SendBuffer.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef SENDBUFFER_H
|
||||
#define SENDBUFFER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QQueue>
|
||||
#include "com_interface.h"
|
||||
|
||||
|
||||
class QTimer;
|
||||
class VMC;
|
||||
enum class SEND_ERROR : quint8;
|
||||
|
||||
#define SB_MAX_RESEND 3
|
||||
#define SB_MAX_SENDQUEUESIZE 10
|
||||
|
||||
|
||||
class SendBuffer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
VMC *vmc;
|
||||
COM_interface *interface;
|
||||
|
||||
QQueue<QByteArray> messageQueue;
|
||||
quint8 resendCounter;
|
||||
|
||||
/* timer for resending messages to vmc, if no valid response is resent from vmc
|
||||
*/
|
||||
QTimer *responseTimeoutTimer;
|
||||
quint8 responseTimerTimeoutCounter;
|
||||
|
||||
void PrivateSendMessage();
|
||||
|
||||
public:
|
||||
explicit SendBuffer(COM_interface *cinterface, QObject *parent = nullptr);
|
||||
~SendBuffer();
|
||||
|
||||
int SendMessage(QByteArray & ba, bool enqueue = false);
|
||||
|
||||
signals:
|
||||
void writeLogSent(QByteArray ba);
|
||||
void sendError(SEND_ERROR error);
|
||||
|
||||
public slots:
|
||||
void onReceiveResponse(quint8 response);
|
||||
void onResponseTimeoutTimerTimeout();
|
||||
};
|
||||
|
||||
|
||||
enum class SEND_ERROR : quint8 {
|
||||
NO_ERROR = 0,
|
||||
RESPONSE,
|
||||
RESPONSE_TIMER_TIMEOUT,
|
||||
MULTIPLE_RESPONSE_TIMER_TIMEOUT
|
||||
};
|
||||
|
||||
#endif // SENDBUFFER_H
|
303
src/ATBAPP/support/VMC/com_interface.cpp
Normal file
303
src/ATBAPP/support/VMC/com_interface.cpp
Normal file
@ -0,0 +1,303 @@
|
||||
#include "com_interface.h"
|
||||
#include <QtDebug>
|
||||
|
||||
#if QT_VERSION >=0x050000
|
||||
#include <QSerialPort>
|
||||
#else
|
||||
#include "qextserialport.h"
|
||||
#endif
|
||||
|
||||
COM_interface::COM_interface(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
#if QT_VERSION >=0x050000
|
||||
port = new QSerialPort(this);
|
||||
#else
|
||||
port = new QextSerialPort(QextSerialPort::EventDriven, this);
|
||||
#endif
|
||||
|
||||
buffer = new QByteArray();
|
||||
}
|
||||
|
||||
|
||||
COM_interface::~COM_interface()
|
||||
{
|
||||
delete buffer;
|
||||
delete port;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* *************************************************************************
|
||||
*
|
||||
* QT5 ( = QSerialPort) specific methodes
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************/
|
||||
#if QT_VERSION >=0x050000
|
||||
|
||||
int COM_interface::open(const QString & portname, int baudrate)
|
||||
{
|
||||
QSerialPort::BaudRate br = QSerialPort::Baud115200;
|
||||
|
||||
switch (baudrate) {
|
||||
case 9600: br = QSerialPort::Baud9600;
|
||||
break;
|
||||
case 57600: br = QSerialPort::Baud57600;
|
||||
break;
|
||||
default: br = QSerialPort::Baud115200;
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "COM_interface::open(): baudrate = " << baudrate;
|
||||
qDebug() << "COM_interface::open(): br = " << br;
|
||||
|
||||
port->setPortName(portname);
|
||||
port->setBaudRate(br);
|
||||
port->setStopBits(QSerialPort::OneStop);
|
||||
port->setParity(QSerialPort::NoParity);
|
||||
port->setDataBits(QSerialPort::Data8);
|
||||
|
||||
|
||||
if (port->open(QIODevice::ReadWrite) == true) {
|
||||
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
|
||||
qDebug() << "listening for data on" << port->portName();
|
||||
|
||||
emit connected();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
qDebug() << "device failed to open:";
|
||||
qDebug() << " device:" << portname;
|
||||
qDebug() << " errorstring:" << port->errorString();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int COM_interface::open(const QString & portname, int baudrate, int dataBits, int stopBits, int parity)
|
||||
{
|
||||
QSerialPort::BaudRate br = QSerialPort::Baud115200;
|
||||
QSerialPort::DataBits db = QSerialPort::Data8;
|
||||
QSerialPort::StopBits sb = QSerialPort::OneStop;
|
||||
QSerialPort::Parity par = QSerialPort::NoParity;
|
||||
|
||||
switch (baudrate) {
|
||||
case 9600: br = QSerialPort::Baud9600;
|
||||
break;
|
||||
case 57600: br = QSerialPort::Baud57600;
|
||||
break;
|
||||
default: br = QSerialPort::Baud115200;
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO Add if needed!
|
||||
switch (dataBits) {
|
||||
default: db = QSerialPort::Data8;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (stopBits) {
|
||||
case 2: sb = QSerialPort::TwoStop;
|
||||
break;
|
||||
default: sb = QSerialPort::OneStop;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (parity) {
|
||||
default: par = QSerialPort::NoParity;
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "COM_interface::open(): baudrate = " << baudrate;
|
||||
qDebug() << "COM_interface::open(): br = " << br;
|
||||
qDebug() << "COM_interface::open(): databits = " << dataBits;
|
||||
qDebug() << "COM_interface::open(): db = " << db;
|
||||
qDebug() << "COM_interface::open(): stopbits = " << stopBits;
|
||||
qDebug() << "COM_interface::open(): sb = " << sb;
|
||||
qDebug() << "COM_interface::open(): parity = " << parity;
|
||||
qDebug() << "COM_interface::open(): par = " << par;
|
||||
|
||||
port->setPortName(portname);
|
||||
port->setBaudRate(br);
|
||||
port->setStopBits(sb);
|
||||
//port->setFlowControl(FLOW_OFF);
|
||||
port->setParity(par);
|
||||
port->setDataBits(db);
|
||||
|
||||
if (port->open(QIODevice::ReadWrite) == true) {
|
||||
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
|
||||
qDebug() << "listening for data on" << port->portName();
|
||||
|
||||
emit connected();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
qDebug() << "device failed to open:";
|
||||
qDebug() << " device:" << portname;
|
||||
qDebug() << " errorstring:" << port->errorString();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* *************************************************************************
|
||||
*
|
||||
* QT4 ( = QextSerialPort) specific methodes
|
||||
*
|
||||
***************************************************************************
|
||||
***************************************************************************/
|
||||
#else
|
||||
|
||||
int COM_interface::open(const QString & portname, int baudrate)
|
||||
{
|
||||
BaudRateType br = BAUD115200;
|
||||
switch (baudrate) {
|
||||
case 9600: br = BAUD9600;
|
||||
break;
|
||||
case 57600: br = BAUD57600;
|
||||
break;
|
||||
default: br = BAUD115200;
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "COM_interface::open(): baudrate = " << baudrate;
|
||||
qDebug() << "COM_interface::open(): br = " << br;
|
||||
|
||||
port->setPortName(portname);
|
||||
port->setBaudRate(br);
|
||||
port->setStopBits(STOP_1);
|
||||
//port->setFlowControl(FLOW_OFF);
|
||||
port->setParity(PAR_NONE);
|
||||
port->setDataBits(DATA_8);
|
||||
port->setTimeout(0);
|
||||
|
||||
if (port->open(QIODevice::ReadWrite) == true) {
|
||||
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
connect(port, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
|
||||
if (!(port->lineStatus() & LS_DSR))
|
||||
qDebug() << "warning: device is not turned on";
|
||||
qDebug() << "listening for data on" << port->portName();
|
||||
|
||||
emit connected();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
qDebug() << "device failed to open:";
|
||||
qDebug() << " device:" << portname;
|
||||
qDebug() << " errorstring:" << port->errorString();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int COM_interface::open(const QString & portname, int baudrate, int dataBits, int stopBits, int parity)
|
||||
{
|
||||
BaudRateType br = BAUD115200;
|
||||
DataBitsType db = DATA_8;
|
||||
StopBitsType sb = STOP_1;
|
||||
ParityType par = PAR_NONE;
|
||||
|
||||
switch (baudrate) {
|
||||
case 9600: br = BAUD9600;
|
||||
break;
|
||||
case 57600: br = BAUD57600;
|
||||
break;
|
||||
default: br = BAUD115200;
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO Add if needed!
|
||||
switch (dataBits) {
|
||||
default: db = DATA_8;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (stopBits) {
|
||||
case 2: sb = STOP_2;
|
||||
break;
|
||||
default: sb = STOP_1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (parity) {
|
||||
default: par = PAR_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "COM_interface::open(): baudrate = " << baudrate;
|
||||
qDebug() << "COM_interface::open(): br = " << br;
|
||||
qDebug() << "COM_interface::open(): databits = " << dataBits;
|
||||
qDebug() << "COM_interface::open(): db = " << db;
|
||||
qDebug() << "COM_interface::open(): stopbits = " << stopBits;
|
||||
qDebug() << "COM_interface::open(): sb = " << sb;
|
||||
qDebug() << "COM_interface::open(): parity = " << parity;
|
||||
qDebug() << "COM_interface::open(): par = " << par;
|
||||
|
||||
port->setPortName(portname);
|
||||
port->setBaudRate(br);
|
||||
port->setStopBits(sb);
|
||||
//port->setFlowControl(FLOW_OFF);
|
||||
port->setParity(par);
|
||||
port->setDataBits(db);
|
||||
port->setTimeout(0);
|
||||
|
||||
if (port->open(QIODevice::ReadWrite) == true) {
|
||||
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
connect(port, SIGNAL(dsrChanged(bool)), this, SLOT(onDsrChanged(bool)));
|
||||
if (!(port->lineStatus() & LS_DSR))
|
||||
qDebug() << "warning: device is not turned on";
|
||||
qDebug() << "listening for data on" << port->portName();
|
||||
|
||||
emit connected();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
qDebug() << "device failed to open:";
|
||||
qDebug() << " device:" << portname;
|
||||
qDebug() << " errorstring:" << port->errorString();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int COM_interface::close(void)
|
||||
{
|
||||
if (port->isOpen()) {
|
||||
port->flush();
|
||||
//port->reset();
|
||||
port->close();
|
||||
port->reset();
|
||||
}
|
||||
emit disconnected();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void COM_interface::onReadyRead(void) {
|
||||
qint64 i;
|
||||
i = 0;
|
||||
buffer->clear();
|
||||
|
||||
while (1) {
|
||||
char c;
|
||||
if (port->read(& c, 1) <= 0)
|
||||
break;
|
||||
qDebug() << "com_interface::onReadyRead(): buffer[" << i << "]: '" << c << "'";
|
||||
buffer->insert(i++,c);
|
||||
}
|
||||
|
||||
emit ReadData(buffer);
|
||||
}
|
||||
|
||||
|
||||
void COM_interface::onDsrChanged(bool state) {
|
||||
// DSR-line is not used with CLR200 reader
|
||||
// so we do nothing on this signal.
|
||||
qDebug() << "onDsrChanged(): state is " << state;
|
||||
}
|
||||
|
||||
|
||||
void COM_interface::putChar(const char c) {
|
||||
port->putChar(c);
|
||||
}
|
53
src/ATBAPP/support/VMC/com_interface.h
Normal file
53
src/ATBAPP/support/VMC/com_interface.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef COM_INTERFACE_H
|
||||
#define COM_INTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#if QT_VERSION >=0x050000
|
||||
class QSerialPort;
|
||||
#else
|
||||
class QextSerialPort;
|
||||
#endif
|
||||
|
||||
|
||||
class COM_interface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
#if QT_VERSION >=0x050000
|
||||
QSerialPort *port;
|
||||
#else
|
||||
QextSerialPort *port;
|
||||
#endif
|
||||
QByteArray *buffer;
|
||||
|
||||
|
||||
public:
|
||||
explicit COM_interface(QObject *parent = nullptr);
|
||||
~COM_interface();
|
||||
|
||||
int open(const QString & portname, int baudrate);
|
||||
int open(const QString & portname, int baudrate, int dataBits, int stopBits, int parity);
|
||||
int close(void);
|
||||
|
||||
void putChar(const char c);
|
||||
|
||||
int isOpen(void);
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
void ReadData(QByteArray *buffer);
|
||||
void connected(void);
|
||||
void disconnected(void);
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
void onReadyRead(void);
|
||||
void onDsrChanged(bool state);
|
||||
};
|
||||
|
||||
#endif // COM_INTERFACE_H
|
1625
src/ATBAPP/support/VMC/vmc.cpp
Normal file
1625
src/ATBAPP/support/VMC/vmc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
394
src/ATBAPP/support/VMC/vmc.h
Normal file
394
src/ATBAPP/support/VMC/vmc.h
Normal file
@ -0,0 +1,394 @@
|
||||
#ifndef VMC_H
|
||||
#define VMC_H
|
||||
|
||||
#include "com_interface.h"
|
||||
#include "VMC/ReceiveBuffer.h"
|
||||
#include "SendBuffer.h"
|
||||
#include "support/VendingData.h"
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QStateMachine>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QList>
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#define VMC_RECEIVE_TIMEOUT 1000
|
||||
|
||||
|
||||
|
||||
|
||||
#define VMC_CMD_SW_VERSION 0x10
|
||||
#define VMC_CMD_STATUS_REQUEST 0x11
|
||||
|
||||
#define VMC_CMD_SCREEN 0x44
|
||||
#define VMC_CMD_LANGUAGE 0x46
|
||||
|
||||
#define VMC_CMD_DISP_LICENCE_PLATE 0x48
|
||||
#define VMC_CMD_DISP_PRODUCT 0x49
|
||||
#define VMC_CMD_DISP_PARKTIME_END 0x50
|
||||
#define VMC_CMD_DISP_PRICE 0x51
|
||||
#define VMC_CMD_DATE_TIME 0x52
|
||||
#define VMC_CMD_DISP_LINE1 0x53
|
||||
#define VMC_CMD_DISP_LINE2 0x54
|
||||
#define VMC_CMD_USER_MESSAGE 0x55
|
||||
#define VMC_CMD_DISP_AMOUNT_TO_PAY 0x56
|
||||
|
||||
#define VMC_CMD_TEXT 0x60
|
||||
#define VMC_CMD_TEXT_ENC 0x61
|
||||
|
||||
#define VMC_CMD_MACHINE_NR 0x62
|
||||
#define VMC_CMD_SYSTEM 0x63
|
||||
#define VMC_CMD_PSA_CONFIG 0x64
|
||||
|
||||
#define VMC_CMD_BUSY 0x66
|
||||
#define VMC_CMD_MESSAGE_BOX 0x67
|
||||
|
||||
#define VMC_CMD_END_PRG 0x70 // kill ATBQT
|
||||
#define VMC_CMD_SHUTDOWN_SYSTEM 0x71 // 'halt'
|
||||
#define VMC_CMD_RESTART_PRG 0x72 // restart ATBQT
|
||||
#define VMC_CMD_RESTART_SYSTEM 0x73 // reboot ptu
|
||||
|
||||
#define VMC_CMD_SCREEN_CFG 0x90
|
||||
|
||||
#define VMC_CMD_FORMATED_STRING 0xD0
|
||||
|
||||
#define VMC_CMD_VMC_SYSTEM 0xE0
|
||||
|
||||
#define VMC_CMD_SCREEN_INVALID 0x00
|
||||
#define VMC_CMD_SCREEN_START 0x30
|
||||
#define VMC_CMD_SCREEN_LICPLT 0x31
|
||||
#define VMC_CMD_SCREEN_PRODUCT 0x32
|
||||
#define VMC_CMD_SCREEN_PARKEND 0x33
|
||||
#define VMC_CMD_SCREEN_PAYMETH 0x34
|
||||
#define VMC_CMD_SCREEN_CREDITCARD 0x35
|
||||
#define VMC_CMD_SCREEN_WAIT_FOR 0x36
|
||||
#define VMC_CMD_SCREEN_GOODBYE 0x37
|
||||
#define VMC_CMD_SCREEN_CASHPAY 0x38
|
||||
#define VMC_CMD_SCREEN_PIN 0x39
|
||||
#define VMC_CMD_SCREEN_RESIDENT 0x3A
|
||||
#define VMC_CMD_SCREEN_GOODBYE2 0x3B
|
||||
#define VMC_CMD_SCREEN_RECEIPT 0x3C
|
||||
#define VMC_CMD_SCREEN_FREEPARK 0x3D
|
||||
#define VMC_CMD_SCREEN_DEFBUTTONS 0x3E
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE1 0x3F
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE2 0x40
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE3 0x41
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE4 0x42
|
||||
#define VMC_CMD_SCREEN_CARDSTATUS 0x43
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE5 0x44
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE6 0x45
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE7 0x46
|
||||
#define VMC_CMD_SCREEN_CREDITCARDABORT 0x47
|
||||
#define VMC_CMD_SCREEN_PAYMETHODE8 0x48
|
||||
#define VMC_CMD_SCREEN_REMOVECARD 0x49
|
||||
#define VMC_CMD_SCREEN_GOODBYE3 0x4A
|
||||
#define VMC_CMD_SCREEN_GENERALABORT 0x4B
|
||||
#define VMC_CMD_SCREEN_ABORT2 0x4C
|
||||
#define VMC_CMD_SCREEN_ABORT3 0x4D
|
||||
#define VMC_CMD_SCREEN_GOODBYE4 0x4E
|
||||
#define VMC_CMD_SCREEN_GOODBYE5 0x4F
|
||||
// note: SCREEN_COMMON is 0x50
|
||||
#define VMC_CMD_SCREEN_FINEPAYMENT 0x51
|
||||
#define VMC_CMD_SCREEN_CREDITCARD2 0x52
|
||||
#define VMC_CMD_SCREEN_CREDITCARD3 0x53
|
||||
#define VMC_CMD_SCREEN_RECEIPT2 0x54
|
||||
#define VMC_CMD_SCREEN_CREDITCARD4 0x55
|
||||
#define VMC_CMD_SCREEN_TWO_PRODUCTS1 0x56
|
||||
#define VMC_CMD_SCREEN_TWO_PRODUCTS2 0x57
|
||||
#define VMC_CMD_SCREEN_PARKTIME1 0x5a
|
||||
#define VMC_CMD_SCREEN_PARKTIME2 0x5b
|
||||
#define VMC_CMD_SCREEN_DATETIME1 0x5c
|
||||
#define VMC_CMD_SCREEN_DATETIME2 0x5d
|
||||
#define VMC_CMD_SCREEN_DIAG 0x60
|
||||
#define VMC_CMD_SCREEN_WELCOME1 0x61
|
||||
#define VMC_CMD_SCREEN_WELCOME2 0x62
|
||||
#define VMC_CMD_SCREEN_WELCOME3 0x63
|
||||
#define VMC_CMD_SCREEN_WELCOME4 0x64
|
||||
#define VMC_CMD_SCREEN_OOO 0x65
|
||||
#define VMC_CMD_SCREEN_WAIT1 0x6A
|
||||
#define VMC_CMD_SCREEN_WAIT2 0x6B
|
||||
#define VMC_CMD_SCREEN_WAIT3 0x6C
|
||||
#define VMC_CMD_SCREEN_WAIT4 0x6D
|
||||
#define VMC_CMD_SCREEN_TARIF 0x70
|
||||
#define VMC_CMD_SCREEN_HELP1 0x71
|
||||
#define VMC_CMD_SCREEN_HELP2 0x72
|
||||
#define VMC_CMD_SCREEN_HELP3 0x73
|
||||
#define VMC_CMD_SCREEN_HELP4 0x74
|
||||
#define VMC_CMD_SCREEN_HELP5 0x75
|
||||
#define VMC_CMD_SCREEN_ABORT4 0x80
|
||||
#define VMC_CMD_SCREEN_ABORT5 0x81
|
||||
#define VMC_CMD_SCREEN_BARCODE 0x82
|
||||
#define VMC_CMD_SCREEN_AGEVERIFICATION 0x83
|
||||
#define VMC_CMD_SCREEN_DEFBUTTONS2 0x84
|
||||
#define VMC_CMD_SCREEN_DEFBUTTONS3 0x85
|
||||
#define VMC_CMD_SCREEN_PRINT2 0x86
|
||||
#define VMC_CMD_SCREEN_PRINT3 0x87
|
||||
#define VMC_CMD_SCREEN_QRCODE_RECEIPT 0x88
|
||||
#define VMC_CMD_SCREEN_LICPLT2 0x90
|
||||
#define VMC_CMD_SCREEN_LICPLT3 0x91
|
||||
#define VMC_CMD_SCREEN_LICPLT4 0x92
|
||||
#define VMC_CMD_SCREEN_ABORT6 0x93
|
||||
#define VMC_CMD_SCREEN_ABORT7 0x94
|
||||
#define VMC_CMD_SCREEN_PARKEND2 0xA0
|
||||
#define VMC_CMD_SCREEN_PARKEND3 0xA1
|
||||
|
||||
|
||||
#define VMC_CMD_SCREEN_COMMON 0x50
|
||||
#define VMC_CMD_SCREEN_MESSAGE_BOX 0xF1
|
||||
// CARD_SERVICE_ERROR_TEXTS 0xFA
|
||||
|
||||
#define ACK 0x06
|
||||
#define NACK 0x15
|
||||
|
||||
class AppControl;
|
||||
class ReceiveBuffer;
|
||||
class SendBuffer;
|
||||
class HMI;
|
||||
class ATBHMIconfig;
|
||||
|
||||
class VMC : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
private:
|
||||
AppControl *main;
|
||||
COM_interface *com_interface;
|
||||
ReceiveBuffer *receiveBuffer;
|
||||
SendBuffer *sendBuffer;
|
||||
|
||||
ATBHMIconfig *config;
|
||||
|
||||
// internal: write a ByteArray to com-port:
|
||||
int SendMessage(QByteArray ba, bool enqueue = false);
|
||||
|
||||
quint16 parseSystemCommand(QByteArray & cmd);
|
||||
quint8 parseTextCommand(QByteArray & cmd);
|
||||
quint8 parseTextCommandEnc(QByteArray & cmd);
|
||||
quint8 parseDataDisplayCommand(QByteArray & cmd);
|
||||
quint8 parseDateCommand(QByteArray & cmd);
|
||||
quint8 parseUserMessageCommand(QByteArray & cmd);
|
||||
quint8 parseLanguageCommand(QByteArray & cmd);
|
||||
quint8 parseBusyCommand(QByteArray & cmd);
|
||||
quint8 parseScreenConfigCommand(QByteArray & cmd);
|
||||
quint8 parsePSAConfigCommand(QByteArray & cmd);
|
||||
quint8 parseShowMessageBoxCommand(QByteArray & cmd);
|
||||
quint8 parseVMCSystemMessage(QByteArray & cmd);
|
||||
quint8 parseVMCFormatedString(QByteArray & cmd);
|
||||
|
||||
QString & privateHandleDataCommand_Amount(quint8 data, QString & dataString);
|
||||
QString & privateHandleDataCommand_AmountToPay(quint8 data, QString & dataString);
|
||||
|
||||
QTimer *sendDelayTimer;
|
||||
QString delayedMessage;
|
||||
|
||||
quint8 flag_blockVMCScreen;
|
||||
quint16 currentCachedScreen;
|
||||
|
||||
private slots:
|
||||
void onDelayedMessageTimerTimeout();
|
||||
|
||||
void skipDiscount();
|
||||
|
||||
public:
|
||||
explicit VMC(QObject *parent = nullptr);
|
||||
VMC(AppControl *main, ATBHMIconfig *config, QObject *parent = nullptr);
|
||||
~VMC();
|
||||
|
||||
int SendMessage(QString msg);
|
||||
int SendMessageDelayed(QString msg, int delay);
|
||||
|
||||
int SendACK();
|
||||
int SendNACK();
|
||||
|
||||
int sendButtonChar(QChar c);
|
||||
|
||||
int SendButton0(); // 0 - 3E 45 31 30 E4
|
||||
int SendButton1(); // 1 - 3E 45 31 31 E5
|
||||
int SendButton2(); // 2 - 3E 45 31 32 E6
|
||||
int SendButton3(); // 3 - 3E 45 31 33 E7
|
||||
int SendButton4(); // 4 - 3E 45 31 34 E8
|
||||
int SendButton5(); // 5 - 3E 45 31 35 E9
|
||||
int SendButton6(); // 6 - 3E 45 31 36 EA
|
||||
int SendButton7(); // 7 - 3E 45 31 37 EB
|
||||
int SendButton8(); // 8 - 3E 45 31 38 EC
|
||||
int SendButton9(); // 9 - 3E 45 31 39 ED
|
||||
|
||||
int SendButtonNext(); // 10 - 3E 45 31 3A EE
|
||||
int SendButtonBack(); // 11 - 3E 45 31 3B EF
|
||||
int SendButtonCancel(); // 12 - 3E 45 31 3C F0
|
||||
|
||||
int SendButtonStart(); // 13 - 3E 45 31 3D F1
|
||||
int SendButtonHelp(); // 14 - 3E 45 31 3E F2
|
||||
int SendButtonTarif(); // 15 - 3E 45 31 3F F3
|
||||
|
||||
int SendButtonStart2(); // - 3E 45 31 A0 cs
|
||||
int SendButtonStart3(); // - 3E 45 31 A1 cs
|
||||
int SendButtonStart4(); // - 3E 45 31 A2 cs
|
||||
|
||||
int SendButtonArrowLeft(); // 16 - 3E 45 31 83 cs
|
||||
int SendButtonArrowRight(); // 17 - 3E 45 31 84 cs -
|
||||
int SendButtonArrowUp(); // 18 - 3E 45 31 85 cs -
|
||||
int SendButtonArrowDown(); // 19 - 3E 45 31 86 cs -
|
||||
|
||||
int SendButtonCardTypeLeft(); // 20 - 3E 45 31 87 cs -
|
||||
int SendButtonCardTypeRight(); // 21 - 3E 45 31 88 cs -
|
||||
|
||||
int SendButtonA(); // 'A' - 3E 45 31 41 F5
|
||||
int SendButtonB(); // 'B' - 3E 45 31 42 F6
|
||||
int SendButtonC(); // 'C' - 3E 45 31 43 F7
|
||||
int SendButtonD(); // 'D' - 3E 45 31 44 F8
|
||||
int SendButtonE(); // 'E' - 3E 45 31 45 F9
|
||||
int SendButtonF(); // 'F' - 3E 45 31 46 FA
|
||||
int SendButtonG(); // 'G' - 3E 45 31 47 FB
|
||||
int SendButtonH(); // 'H' - 3E 45 31 48 FC
|
||||
int SendButtonI(); // 'I' - 3E 45 31 49 FD
|
||||
int SendButtonJ(); // 'J' - 3E 45 31 4A FE
|
||||
int SendButtonK(); // 'K' - 3E 45 31 4B FF
|
||||
int SendButtonL(); // 'L' - 3E 45 31 4C 00
|
||||
int SendButtonM(); // 'M' - 3E 45 31 4D 01
|
||||
int SendButtonN(); // 'N' - 3E 45 31 4E 02
|
||||
int SendButtonO(); // 'O' - 3E 45 31 4F 03
|
||||
int SendButtonP(); // 'P' - 3E 45 31 50 04
|
||||
int SendButtonQ(); // 'Q' - 3E 45 31 51 05
|
||||
int SendButtonR(); // 'R' - 3E 45 31 52 06
|
||||
int SendButtonS(); // 'S' - 3E 45 31 53 07
|
||||
int SendButtonT(); // 'T' - 3E 45 31 54 08
|
||||
int SendButtonU(); // 'U' - 3E 45 31 55 09
|
||||
int SendButtonV(); // 'V' - 3E 45 31 56 0A
|
||||
int SendButtonW(); // 'W' - 3E 45 31 57 0B
|
||||
int SendButtonX(); // 'X' - 3E 45 31 58 0C
|
||||
int SendButtonY(); // 'Y' - 3E 45 31 59 0D
|
||||
int SendButtonZ(); // 'Z' - 3E 45 31 5A 0E
|
||||
int SendButtonUE(); // 'Ü' - 3E 45 31 DC - ISO 8859-1 (Latin-1): 'Ü'
|
||||
int SendButtonOE(); // 'Ö' - 3E 45 31 D6 - ISO 8859-1 (Latin-1): 'Ö'
|
||||
int SendButtonAE(); // 'Ä' - 3E 45 31 C4 - ISO 8859-1 (Latin-1): 'Ä'
|
||||
|
||||
int SendButtonDEL(); // DELL - 3E 45 31 7F 33
|
||||
|
||||
int SendButtonDash(); // '-' - 3E 45 31 2D E1
|
||||
int SendButtonSpace(); // ' ' - 3E 45 31 20 D4
|
||||
|
||||
int SendButtonClose(); // - 3E 45 31 80 cs
|
||||
int SendButtonYes(); // - 3E 45 31 81 cs
|
||||
int SendButtonNo(); // - 3E 45 31 82 cs
|
||||
|
||||
int SendButtonVehicleDefintion1(); // 0x90 - 3E 45 31 90 cs
|
||||
int SendButtonVehicleDefintion2(); // 0x91 - 3E 45 31 91 cs
|
||||
int SendButtonVehicleDefintion3(); // 0x92 - 3E 45 31 92 cs
|
||||
int SendButtonVehicleDefintion4(); // 0x93 - 3E 45 31 93 cs
|
||||
int SendButtonVehicleDefintion5(); // 0x94 - 3E 45 31 94 cs
|
||||
int SendButtonVehicleDefintion6(); // 0x95 - 3E 45 31 95 cs
|
||||
int SendButtonVehicleDefintion7(); // 0x96 - 3E 45 31 96 cs
|
||||
int SendButtonVehicleDefintion8(); // 0x97 - 3E 45 31 97 cs
|
||||
|
||||
int SendButtonPaymethode1(); // 0x98 - 3E 45 31 98 cs
|
||||
int SendButtonPaymethode2(); // 0x99 - 3E 45 31 99 cs
|
||||
int SendButtonPaymethode3(); // 0x9a - 3E 45 31 9a cs
|
||||
int SendButtonPaymethode4(); // 0x9b - 3E 45 31 9b cs
|
||||
|
||||
int SendSystemMessage(quint8 nr); // 0xF0 - 3E F0 31 nr cs
|
||||
int SendSystemMessageStart(); // 0xF0 - 3E F0 31 31 cs
|
||||
int SendSystemMessageTimeout(); // 0xF0 - 3E F0 31 32 cs
|
||||
|
||||
|
||||
|
||||
int SendButtonServiceOK(QString MessageString);
|
||||
|
||||
// deprecated:
|
||||
int SendLicPlate(QString licplate);
|
||||
int SendBarcode(QString barcode);
|
||||
int SendAmountDueTax(QString amount);
|
||||
int SendAmountDueNet(QString amount);
|
||||
int SendAmountDuePeriodStart(QString startTime);
|
||||
int SendAmountDuePeriodEnd(QString endTime);
|
||||
int SendCracePeriod(QString minute);
|
||||
int SendGeneratedPinNumber(QString pin);
|
||||
|
||||
// from former "Bewonerscode": send code and id
|
||||
int SendId(QString id);
|
||||
int SendCode(QString code);
|
||||
|
||||
|
||||
int SendFormatedString(QString formatString);
|
||||
int SendFormatedStringError(QString errorString);
|
||||
|
||||
int SendLangSwitch(quint8 nr);
|
||||
|
||||
int SendVersion(QString VersionString); // 3E 10 14 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. CRC
|
||||
|
||||
int SendCurrentState();
|
||||
|
||||
void blockScreenSwitch(quint8 mode);
|
||||
quint16 getCurrentCachedScreen();
|
||||
|
||||
signals:
|
||||
void CommandProcessed(); // sent to ReceiveBuffer if a command is processed
|
||||
|
||||
void retriggerModeSell();
|
||||
|
||||
void setBusy();
|
||||
void resetBusy();
|
||||
|
||||
void showMessageBox(quint8 type, quint8 text);
|
||||
|
||||
void sysCommand(quint16 cmd, QByteArray data);
|
||||
//void PSAconfig(quint16 cust_nr, quint16 group_nr, quint16 zone_nr, quint16 machine_nr);
|
||||
void setCustNr(const QString & cust_nr);
|
||||
void setGroupNr(const QString & group_nr);
|
||||
void setZoneNr(const QString & zone_nr);
|
||||
void setMachineNr(const QString & machine_nr);
|
||||
void displayData(quint8 infoFild, QString text);
|
||||
void newDateTime(const QString & dateTimeString);
|
||||
|
||||
void setLanguage(quint8 lang);
|
||||
void setDefaultLanguage(quint8 lang);
|
||||
|
||||
|
||||
void userMessage(quint8 messagenr, quint8 action);
|
||||
|
||||
void writeLog(QString str);
|
||||
void writeLogReceived(QByteArray ba);
|
||||
void writeLogSent(QByteArray ba);
|
||||
|
||||
void wakeVMC();
|
||||
|
||||
void ccStartTransaction();
|
||||
void ccConfirmTransaction();
|
||||
void ccCancelTransaction();
|
||||
void ccStartPreauthorisation();
|
||||
void ccConfirmPreauthorisation();
|
||||
void ccCancelPreauthorisation();
|
||||
void ccStartReadCard();
|
||||
|
||||
void ccWakup();
|
||||
void ccSleep();
|
||||
|
||||
#ifdef USE_BARCODESCANNER
|
||||
void requestNewBarcode();
|
||||
#endif
|
||||
|
||||
void VMCSystemSellingProcessStart();
|
||||
void VMCSystemSellingProcessStop();
|
||||
void VMCSystemTransactionSuccess();
|
||||
|
||||
void VMCFormatedString(FormatedStringList);
|
||||
|
||||
void setVendingData(QString key, QByteArray value);
|
||||
|
||||
public slots:
|
||||
void CommandAvaliable(QByteArray message); // called when a message is in receive buffer
|
||||
void onReceiveError(RECEIVE_ERROR error); // for response on wrong vmc commands
|
||||
void onSendError(SEND_ERROR error); // for react on e.g. a non answering vmc
|
||||
|
||||
int SendLongFormatedString(QString formatString);
|
||||
int SendLongFormatedStringReference(QString & formatedString);
|
||||
|
||||
void ccStartTransactionRequest(); // called to start/restart a CC transaction
|
||||
void ccStartConfirmTransaction(); // called to start confirmation
|
||||
void ccPrintReceipt(QString receipt); // called to send receipt to vmc
|
||||
};
|
||||
|
||||
#endif // VMC_H
|
76
src/ATBAPP/support/VendingData.cpp
Normal file
76
src/ATBAPP/support/VendingData.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "VendingData.h"
|
||||
#include <QDebug>
|
||||
#include "ATBAPP.h"
|
||||
#include "version.h"
|
||||
|
||||
VendingData::VendingData(QObject *parent) : QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<FormatedStringList>("FormatedStringList");
|
||||
}
|
||||
|
||||
|
||||
QVariant VendingData::getParameter(const QString & key)
|
||||
{
|
||||
|
||||
#if defined (ARCH_DesktopLinux)
|
||||
// note: QVariant.toString() returns empty string for custom types
|
||||
|
||||
if (QString::compare(hash.value(key).typeName(), "APP_ACTION") == 0) {
|
||||
APP_ACTION action = hash.value(key).value<APP_ACTION>();
|
||||
qDebug() << "VendingData::getParameter() key = " << key << " value = " << action;
|
||||
}
|
||||
else {
|
||||
qDebug() << "VendingData::getParameter() key = " << key << " value = " << hash.value(key).toString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return hash.value(key);
|
||||
}
|
||||
|
||||
void VendingData::setParameter(const QString & key, QVariant value)
|
||||
{
|
||||
|
||||
#if defined (ARCH_DesktopLinux)
|
||||
// note: QVariant.toString() returns empty string for custom types
|
||||
if (QString::compare(value.typeName(), "APP_ACTION") == 0) {
|
||||
APP_ACTION action = value.value<APP_ACTION>();
|
||||
qDebug() << "VendingData::setParameter() key = " << key << " value = " << action;
|
||||
}
|
||||
else {
|
||||
qDebug() << "VendingData::setParameter() key = " << key << " value = " << value.toString();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
this->hash.insert(key, value);
|
||||
}
|
||||
|
||||
void VendingData::clearParameter(const QString & key)
|
||||
{
|
||||
this->hash.remove(key);
|
||||
}
|
||||
|
||||
bool VendingData::hasParameter(const QString & key)
|
||||
{
|
||||
return hash.contains(key);
|
||||
}
|
||||
|
||||
void VendingData::clear()
|
||||
{
|
||||
this->hash.clear();
|
||||
}
|
||||
|
||||
|
||||
uint VendingData::getUintParameter(const QString & key)
|
||||
{
|
||||
qDebug() << "VendingData::getUintParameter() key = " << key << " value = " << hash.value(key).toString();
|
||||
|
||||
uint returnValue = 0;
|
||||
bool ok;
|
||||
|
||||
returnValue = hash.value(key).toString().toUInt(&ok);
|
||||
if (!ok) returnValue = 0;
|
||||
|
||||
return returnValue;
|
||||
}
|
37
src/ATBAPP/support/VendingData.h
Normal file
37
src/ATBAPP/support/VendingData.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef VENDINGDATA_H
|
||||
#define VENDINGDATA_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
typedef QList<QByteArray> FormatedStringList;
|
||||
|
||||
|
||||
class VendingData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QHash<QString, QVariant> hash;
|
||||
|
||||
public:
|
||||
explicit VendingData(QObject *parent = nullptr);
|
||||
|
||||
QVariant getParameter(const QString & key);
|
||||
void setParameter(const QString & key, QVariant value);
|
||||
void clearParameter(const QString & key);
|
||||
bool hasParameter(const QString & key);
|
||||
|
||||
uint getUintParameter(const QString & key);
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
};
|
||||
|
||||
#endif // VENDINGDATA_H
|
Loading…
Reference in New Issue
Block a user