Add first version which at least complies.
This commit is contained in:
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
|
Reference in New Issue
Block a user