Compare commits

..

7 Commits

55 changed files with 18582 additions and 7641 deletions

28
DCPlugin.pri Normal file
View File

@ -0,0 +1,28 @@
INCLUDEPATH += $${PWD}/include
DEPENDPATH += $${PWD}
HEADERS += $${PWD}/include/com.h \
$$PWD/include/datei.h \
$${PWD}/include/controlBus.h \
$${PWD}/include/datIf.h \
$${PWD}/include/dcBL.h \
$${PWD}/include/hwapi.h \
$${PWD}/include/interfaces.h \
$${PWD}/include/prot.h \
$${PWD}/include/sendWRcmd.h \
$${PWD}/include/storeINdata.h \
$${PWD}/include/tslib.h \
$${PWD}/include/shared_mem_buffer.h
SOURCES += $${PWD}/src/com.cpp \
$$PWD/src/datei.cpp \
$$PWD/src/main.cpp \
$${PWD}/src/controlBus.cpp \
$${PWD}/src/datIf.cpp \
$${PWD}/src/dcBL.cpp \
$${PWD}/src/hwapi.cpp \
$${PWD}/src/prot.cpp \
$${PWD}/src/sendWRcmd.cpp \
$${PWD}/src/storeINdata.cpp \
$${PWD}/src/tslib.cpp \
$${PWD}/src/shared_mem_buffer.cpp

View File

@ -4,7 +4,7 @@ CONFIG += plugin
#CONFIG -= app_bundle
#QT += widgets
QT -= gui
QT += serialport
QT += widgets serialport
INCLUDEPATH += $${PWD}/plugins
INCLUDEPATH += $${PWD}/include
@ -14,30 +14,27 @@ QMAKE_CXXFLAGS += -Wno-deprecated-copy
# default
ARCH = PTU5
contains( CONFIG, DesktopLinux ) {
QMAKE_CC = ccache $$QMAKE_CC
QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++11
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++17
# QMAKE_CXXFLAGS += -Wno-deprecated-ctor
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
ARCH = DesktopLinux
include(DCPlugin.pri)
}
contains( CONFIG, PTU5 ) {
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++11
QMAKE_CXXFLAGS += -std=c++17
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
CONFIG += link_pkgconfig
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5
INCLUDEPATH += $$PTU5BASEPATH/qt/libs/deviceController/include/
LIBS += -L$$PTU5BASEPATH/qt/libs/deviceController/library
LIBS += -lCAslave
LIBS += -lCAmaster
# NOTE: include contents of DCPlugin.pri. Also used by ATBQT.
# Add new files in DCPlugin.pri.
include(DCPlugin.pri)
}
contains( CONFIG, PTU5_YOCTO ) {
@ -45,16 +42,15 @@ contains( CONFIG, PTU5_YOCTO ) {
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5
LIBS += -lCAslave
LIBS += -lCAmaster
# add qmqtt lib
#LIBS += -lQt5Qmqtt
}
TARGET = ATBDeviceControllerPlugin
TARGET = CashAgentLib
#DESTDIR = ../plugins
INTERFACE = DeviceController
INTERFACE_DEFINITION = $${PWD}/src/ATBAPP/DeviceControllerInterface.h
INTERFACE_DEFINITION = $${PWD}/include/ATBAPP/DeviceControllerInterface.h
DEFINES += DEVICECONTROLLERPLUGIN_LIBRARY
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
@ -74,36 +70,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
#else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target
# ATBAPP interface
HEADERS += \
src/ATBAPP/ATBAPPplugin.h \
src/ATBAPP/DeviceControllerDiag.h \
src/ATBAPP/DeviceControllerInterface.h \
src/ATBAPP/ATBHealthEvent.h \
src/ATBAPP/ATBMachineEvent.h \
src/ATBAPP/ATBDeviceControllerPlugin.h \
src/ATBAPP/Utils.h \
src/ATBAPP/support/CashUtils.h \
src/ATBAPP/support/DBusControllerInterface.h \
src/ATBAPP/support/JSON.h \
src/ATBAPP/support/PTUSystem.h \
src/ATBAPP/support/PersistentData.h \
src/ATBAPP/support/Ticket.h \
src/ATBAPP/support/TicketUtils.h
SOURCES += \
src/ATBAPP/ATBHealthEvent.cpp \
src/ATBAPP/ATBMachineEvent.cpp \
src/ATBAPP/ATBDeviceControllerPlugin.cpp \
src/ATBAPP/DeviceControllerDiag.cpp \
src/ATBAPP/Utils.cpp \
src/ATBAPP/support/CashUtils.cpp \
src/ATBAPP/support/DBusControllerInterface.cpp \
src/ATBAPP/support/JSON.cpp \
src/ATBAPP/support/PTUSystem.cpp \
src/ATBAPP/support/PersistentData.cpp \
src/ATBAPP/support/Ticket.cpp \
src/ATBAPP/support/TicketUtils.cpp
DISTFILES += \
generate-version.sh
@ -118,3 +86,5 @@ version.input = VERSION_H
version.variable_out = HEADERS
QMAKE_EXTRA_COMPILERS += version
QMAKE_CLEAN += $${PWD}/include/version.h
HEADERS +=

View File

@ -70,8 +70,6 @@ fi
#
#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:

105
include/com.h Normal file
View File

@ -0,0 +1,105 @@
//CAT is always master, no receive before request
#ifndef SER_H
#define SER_H
#include <stdint.h>
#include <QMainWindow>
#include <QString>
#include <QTimer>
#include <QSerialPort>
#include "tslib.h"
#include "controlBus.h"
#define MAXTELEGRAMLEN 90
// display all inputs and outputs in output window:
//#define PRINTALLDEBUGS 1
class T_com : public QMainWindow //, public QPlainTextEdit
{
Q_OBJECT
// complete send message (protocol frame)
QByteArray sendBuffer; //[MAXTELEGRAMLEN];
uint16_t sendLen; // >0: Daten Sendebereit, nach senden wieder auf 0 setzen
// right after reception:
QByteArray rawInput; //[MAXTELEGRAMLEN];
uint16_t rawInLen; // 0: keine neuen Daten erhalten
// QSerialPort *CatSerial = nullptr;
QSerialPort *CatSerial;
//char oeffneSerialPort();
char open_Serial_Port();
void closeSerialPort();
void receiveByLength(void);
private slots:
void readSomeBytes(void);
void serialSendComplete(void);
//void incomingWake(void); //bool LevelOfTheBit);
void receiveTO(void);
void ser_ISR100ms();
public:
T_com(QWidget *parent = nullptr);
~T_com();
QTimer *serRecTime;
bool isPortOpen(void);
void writeToSerial(const QByteArray &data, uint16_t sendLength);
void receiveFixLen(int64_t nrOfbytesToReceive);
bool readFromSerial(QByteArray &data, uint16_t &sendLength);
// retval: true: data available
/*
uint8_t getAllPortPins(void);
// rs232pins: all signals bitwise coded in one byte:
// readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output)
// unused inputs: bit1=RxD bit 3=DCD bit 5 = RING
// handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80)
bool getHSin_CTS(void);
// return the CTS Handshake input): true= high level (+8V)
bool getHSin_DSR(void);
// return the DSR Handshake input): true= high level (+8V)
bool setHSout_RTS(bool hsout);
// hsout true=positiv voltage +12V false= -12V
// retval: true=setting OK
bool setHSout_DTR(bool hsout);
// hsout true=positiv voltage +12V false= -12V
// retval: true=setting OK
*/
signals:
void receivingFinished();
void sendingFinished();
//void wasWokenBySerialHandshake();
};
#endif // SER_H

194
include/controlBus.h Normal file
View File

@ -0,0 +1,194 @@
#ifndef CONTROLBUS_H
#define CONTROLBUS_H
#include <stdint.h>
#include "tslib.h"
#include <QString>
// ///////////////////////////////////////////////////////////////////////////////////
// control serial interface gui <--> serial
// ///////////////////////////////////////////////////////////////////////////////////
void epi_setSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect);
// Actions: open serial port with parameters
void epi_closeSerial(void);
// Actions: close serial port
// Actions, GUI Buttons -> API, start cyclic transmission
void epi_startEmmision(char start); // 1: start sending activated
//void epi_setPeriodicSendTimeVal(uint16_t val);
// Port -> API
void gpi_serialChanged(void);
// serial confirms that port was closed or opened
// Actions, API -> serialPort
uint8_t gpi_getSerialConn(void); // connect if 1, disconnect if 0
int gpi_getBaudNr(void);
QString gpi_getComPortName(void);
void gpi_serialIsOpen(bool offen);
bool epi_isSerialPortOpen();
// true: port is open false: port is closed
// Meldung von TabCom an Datif: starte zyklische Sendung:
bool gpi_isEmmisionOn(void);
//uint16_t gpi_getPeriodicSendTimeVal();
//bool gpi_PeriodicSendTimeHasChanged();
//void epi_setCurrSlavAddr(int slavAd);
//int gpi_getCurrSlavAddr(void);
// ///////////////////////////////////////////////////////////////////////////////////
// Status Display gui <--> serial
// ///////////////////////////////////////////////////////////////////////////////////
//---------------------
// Statuszeile COM Port (serial Port) (open, closed)
// Display in tab_com
QString epi_getTxt4comStateLine(void);
void epi_clrTxt4comStateLine();
// GUI: get Text for serial Comport-State Line
//---------------------
// Statuszeile Handshakes (serial Control) flow.cpp
// geht überhaupt was raus? kommt überhaupt was zurück?
// I
QString epi_getTxt4HsStateLine(void);
void epi_clrTxt4HsStateLine();
// GUI: get Text
// II Master receive state (empfangenes Telgramm OK? crc? length? )
// Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp)
QString epi_getTxt4masterStateLine(void);
void epi_clrTxt4masterStateLine();
// III Slave receive (from Master) OK? if then show results, if not then show errors
// entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR
// Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch
// nicht verwenden und nichts ausgeben oder einlesen
QString epi_getTxt4resultStateLine(void);
void epi_clrTxt4resultStateLine();
// IV Statuszeile Sende- und Empfangsdaten (Datif)
// Display in tab_com
QString epi_getTxt4dataStateLine(void);
void epi_clrTxt4dataStateLine();
// GUI: get Text for serial Comport-State Line
// V, unten, Datif
QString epi_getTxt4datifLine(void);
void epi_clrTxt4datifLine();
//---------------------
// sende-empfangs-Rohdaten-Fenster
// Display in tab_com
QString epi_getTxt4RsDiagWin(void);
void epi_clrTxt4RsDiagWin();
QString epi_get2ndTxt4RsDiagWin(void);
void epi_clr2ndTxt4RsDiagWin();
// Statuszeile COM Port (serial Port) (open, closed)
// Display in tab_com
void gpi_setTxt4comStateLine(QString txtline);
// serial: write Text to be displayed in serial Comport-State line (like "connected")
// used in vcp.cpp, links in tabCom
// Statuszeile Handshakes (serial Control)
// I obere Zeile
void gpi_setTxt4HsStateLine(QString txtline);
// used in flow.cc
// II
void gpi_setTxt4masterStateLine(QString txtline);
// III
void gpi_setTxt4resultStateLine(QString txtline);
// IV
void gpi_setTxt4dataStateLine(QString txtline);
// serial: write Text to be displayed in serial Comport-State line (like "connected")
// used in prot.cpp
// V unten:
void gpi_setTxt4datifLine(QString txtline);
// sende-empfangs-Rohdaten-Fenster
// Display in tab_com
void gpi_setTxt4RsDiagWin(QString txtline);
void gpi_set2ndTxt4RsDiagWin(QString txtline);
// ///////////////////////////////////////////////////////////////////////////////////
// Memory for Slave responses, common data
// ///////////////////////////////////////////////////////////////////////////////////
bool epi_getResult_serialTestOK();
// retval: true: test was successful, got right response
// result of serial line test, slave sent fixed string
void gpi_storeResult_serialTestOK(bool wasOn);
// ///////////////////////////////////////////////////////////////////////////////////
// restore just received data
// ///////////////////////////////////////////////////////////////////////////////////
uint8_t gpi_startNewRequest();
// called by Datif
uint8_t gpi_storeResultOfLastRequest(bool answisok);
// written by Datif
uint8_t epi_getResultOfLastRequest();
// retval: 0: in progress 1: OK 2: error
void gpi_storeRecPayLoad(uint8_t RdDlen, uint8_t *receivedData);
// stored by Datif
uint16_t epi_getLastPayLoad(uint16_t plBufSiz, uint8_t *payLoad);
// get data back in *pl, max 64 byte
// retval = nr of bytes received. If host buffer too small then
// only plBufSíz bytes are copied to pl
// plBufSíz=size of host buffer
#endif

338
include/datIf.h Normal file
View File

@ -0,0 +1,338 @@
// Data Interface between slave (DC) and pi buffer
// determines sending and receiving order of data
// cares for storing input data and restoring output data
#ifndef DIF_H
#define DIF_H
#include <stdint.h>
#include "tslib.h"
#include "prot.h"
#include "dcBL.h"
#include <QMainWindow>
#include <QString>
#include <QTimer>
#include <QDebug>
#include <QDateTime>
#include <QDate>
#include <QTime>
#define CMD2DC_sendTime 20
#define CMD2DC_setWakeFrequ 112
#define CMD2DC_MOV_UPLOCK 113
#define CMD2DC_MOV_DNLOCK 114
#define CMD2DC_UPPER_DOOR 115
#define CMD2DC_LOWER_DOOR 116
#define CMD2DC_VAULT_DOOR 117
#define CMD2DC_REJMOT_ON 118
#define CMD2DC_REJMOT_RUN 119
#define CMD2DC_LED_COIN 100
#define CMD2DC_LED_ILLU 101
#define CMD2DC_LED_TICKET 102
#define CMD2DC_LED_START 104
#define CMD2DC_LED_PIN 103
#define CMD2DC_LED_IN 105
#define CMD2DC_FAN 106
#define CMD2DC_SIREN 107
#define CMD2DC_BARRIER 108
#define CMD2DC_WAKEPTU 109
#define CMD2DC_SWITCHAUXPWR 110
#define CMD2DC_SWITCHAUXDDR 18
#define CMD2DC_SWITCHAUXOUT 19
#define CMD2DC_UCONTACTON 111
#define CMD2DC_DEVICE_PARAM 23
#define CMD2DC_SEND_MACH_ID 11
#define CMD2DC_RDBK_DEV_PARA 14
#define CMD2DC_RDBK_MACH_ID 15
#define CMD2DC_MDB_ON 120
#define CMD2DC_MDB_GET_STATE 107 // REQ
#define CMD2DC_MDB_DORESET 121
#define CMD2DC_MDB_SETWAK 122
//#define CMD2DC_MDB_GETWAK 0x2812 // REQ not nec.
#define CMD2DC_MDB_SENDCMD 123
#define CMD2DC_MDB_SENDMSG 12
#define CMD2DC_MDB_GETRESP 22 // REQ
#define CMD2DC_EMP_SET 24
#define CMD2DC_EMP_GET_ALL 23 // REQ
#define CMD2DC_EMP_STARTPOLL 124
#define CMD2DC_EMP_STARTPAY 125
#define CMD2DC_EMP_STOPPAY 126
#define CMD2DC_EMP_GOTCOIN 108 // REQ
#define CMD2DC_SHUTTER_OPEN 129
#define CMD2DC_ESCR_OPEN 132
#define CMD2DC_ESCR_TAKE 133
#define CMD2DC_ESCR_RETURN 134
#define CMD2DC_MOD_ON 135
#define CMD2DC_MOD_WAK 136
#define CMD2DC_CRED_ON 137
#define CMD2DC_CRED_WAK 138
// READ Commands ((e.g. get input)
#define CMD2DC_TestSerial 10
#define CMD2DC_GetSerialConfig 105
#define CMD2DC_RdBkHWversion 11
#define CMD2DC_RdBkSWversion 12
#define CMD2DC_RdBkDCstate 101
#define CMD2DC_RdBkUID 18
#define CMD2DC_RdBkTime 104
#define CMD2DC_RdBkAnalog 106
#define CMD2DC_GetAllInputs 102
#define CMD2DC_RdBkAllOutputs 103
#define CMD2DC_MIFREADERON 127
#define CMD2DC_ATB_CREATE 128
// Mif read data:
#define CMD2DC_RdBk_MifState 109
#define CMD2DC_RdBk_MifData 24
#define CMD2DC_RdBk_AtbCardType 25
#define CMD2DC_SHUTTER_COIN 131
#define CMD2DC_SHUTTER_OPEN3S 130
#define CMD2DC_SEND_SHUT_TIME 0x2915
#define CMD2DC_ESCR_TAKE 133
#define CMD2DC_ESCR_RETURN 134
#define CMD2DC_PRINTERON 139
#define CMD2DC_RdBk_PrnState 110
#define CMD2DC_RdBk_PrnFonts 26
#define CMD2DC_RdBk_AllPrnData 27
// nr of params:
#define CMD2DC_PRI_SYS_CMD 25 // 3
#define CMD2DC_PRI_ESC_CMD 26 // 4
#define CMD2DC_PRI_SETUP 27 // 5
#define CMD2DC_PRI_MOVE 140 // 2
#define CMD2DC_PRI_SETFONT 141 // 4
#define CMD2DC_PRI_SETLETTER 142 // 3
#define CMD2DC_PRI_CUT 143 // 1
#define CMD2DC_PRI_PRINT_TXT 13 // 64
#define CMD2DC_PRI_LF 144 // 1
#define CMD2DC_PRI_PRIFONTTABLE 145
#define CMD2DC_PRI_BARCODE 14 // ca 15...25
#define CMD2DC_STOR_QR_DATA 15 // 150
#define CMD2DC_PRI_QR_CODE 146 // 0
#define CMD2DC_PRI_LOGOFROMFLASH 147 // 2
#define CMD2DC_PRI_STORE_DOC 16 // 1
#define CMD2DC_PRI_DOCUMENT_NR 17 // 1 + 64
#define CMD2DC_PRI_CLEAR_DOC 148 // 1
/*
// WRITE Commands (e.g. switch relay)
#define CMD2DC_sendTime 0x1310
#define CMD2DC_setWakeFrequ 0x1320
#define CMD2DC_MOV_UPLOCK 0x1801
#define CMD2DC_MOV_DNLOCK 0x1802
#define CMD2DC_UPPER_DOOR 0x1810
#define CMD2DC_LOWER_DOOR 0x1811
#define CMD2DC_VAULT_DOOR 0x1812
// neu 7.10.21:
#define CMD2DC_REJMOT_ON 0x1813
#define CMD2DC_REJMOT_RUN 0x1814
#define CMD2DC_LED_COIN 0x1204
#define CMD2DC_LED_ILLU 0x1205
#define CMD2DC_LED_TICKET 0x1206
#define CMD2DC_LED_START 0x1208
#define CMD2DC_LED_PIN 0x1207
#define CMD2DC_LED_IN 0x1209
#define CMD2DC_FAN 0x1210
#define CMD2DC_SIREN 0x1211
#define CMD2DC_BARRIER 0x1212
#define CMD2DC_WAKEPTU 0x1218
#define CMD2DC_SWITCHAUXPWR 0x1220
#define CMD2DC_SWITCHAUXDDR 0x1222
#define CMD2DC_SWITCHAUXOUT 0x1224
#define CMD2DC_UCONTACTON 0x1226
#define CMD2DC_DEVICE_PARAM 0x2000
#define CMD2DC_SEND_MACH_ID 0x2002
#define CMD2DC_RDBK_DEV_PARA 0x2001
#define CMD2DC_RDBK_MACH_ID 0x2003
// --------------------------- MDB --------------
#define CMD2DC_MDB_ON 0x2800
#define CMD2DC_MDB_GET_STATE 0x2801 // REQ
#define CMD2DC_MDB_DORESET 0x2802
#define CMD2DC_MDB_SETWAK 0x2811
//#define CMD2DC_MDB_GETWAK 0x2812 // REQ not nec.
#define CMD2DC_MDB_SENDCMD 0x2820
#define CMD2DC_MDB_SENDMSG 0x2821
#define CMD2DC_MDB_GETRESP 0x2822 // REQ
// --------------------------- EMP --------------
#define CMD2DC_EMP_SET 0x2830
#define CMD2DC_EMP_GET_ALL 0x2831 // REQ
#define CMD2DC_EMP_STARTPOLL 0x2832
#define CMD2DC_EMP_STARTPAY 0x2834
#define CMD2DC_EMP_STOPPAY 0x2836
#define CMD2DC_EMP_GOTCOIN 0x2837 // REQ
#define CMD2DC_SHUTTER_OPEN 0x2911
#define CMD2DC_ESCR_OPEN 0x2920
#define CMD2DC_ESCR_TAKE 0x2921
#define CMD2DC_ESCR_RETURN 0x2922
#define CMD2DC_MOD_ON 0x2940
#define CMD2DC_MOD_WAK 0x2941
#define CMD2DC_CRED_ON 0x2960
#define CMD2DC_CRED_WAK 0x2961
// READ Commands ((e.g. get input)
#define CMD2DC_TestSerial 0x1101
#define CMD2DC_GetSerialConfig 0x1107
#define CMD2DC_RdBkHWversion 0x110A
#define CMD2DC_RdBkSWversion 0x110B
#define CMD2DC_RdBkDCstate 0x110C
#define CMD2DC_RdBkUID 0x1305
#define CMD2DC_RdBkTime 0x1313
#define CMD2DC_RdBkAnalog 0x1550
#define CMD2DC_GetAllInputs 0x1201
#define CMD2DC_RdBkAllOutputs 0x1202
#define CMD2DC_MIFREADERON 0x2900
#define CMD2DC_ATB_CREATE 0x2907
// Mif read data:
#define CMD2DC_RdBk_MifState 0x2902
#define CMD2DC_RdBk_MifData 0x2903
#define CMD2DC_RdBk_AtbCardType 0x2905
//#define CMD2DC_RdBk_CardData 0x2906
// higher Level operation commands
//#define CMD2DC_SHUTTER_ONE 0x2912
#define CMD2DC_SHUTTER_COIN 0x2913
#define CMD2DC_SHUTTER_OPEN3S 0x2912
#define CMD2DC_SEND_SHUT_TIME 0x2915
#define CMD2DC_ESCR_TAKE 0x2921
#define CMD2DC_ESCR_RETURN 0x2922
#define CMD2DC_PRINTERON 0x2A01
#define CMD2DC_RdBk_PrnState 0x2A02
#define CMD2DC_RdBk_PrnFonts 0x2A12
#define CMD2DC_RdBk_AllPrnData 0x2A40
// nr of params:
#define CMD2DC_PRI_SYS_CMD 0x2A03 // 3
#define CMD2DC_PRI_ESC_CMD 0x2A04 // 4
#define CMD2DC_PRI_SETUP 0x2A05 // 5
#define CMD2DC_PRI_MOVE 0x2A06 // 2
#define CMD2DC_PRI_SETFONT 0x2A10 // 4
#define CMD2DC_PRI_SETLETTER 0x2A11 // 3
#define CMD2DC_PRI_CUT 0x2A13 // 1
#define CMD2DC_PRI_PRINT_TXT 0x2A14 // 64
#define CMD2DC_PRI_LF 0x2A15 // 1
#define CMD2DC_PRI_PRIFONTTABLE 0x2A16
#define CMD2DC_PRI_BARCODE 0x2A17 // ca 15...25
#define CMD2DC_STOR_QR_DATA 0x2A18 // 150
#define CMD2DC_PRI_QR_CODE 0x2A19 // 0
#define CMD2DC_PRI_LOGOFROMFLASH 0x2A1A // 2
#define CMD2DC_PRI_STORE_DOC 0x2A41 // 1
#define CMD2DC_PRI_DOCUMENT_NR 0x2A42 // 1 + 64
#define CMD2DC_PRI_CLEAR_DOC 0x2A43 // 1
*/
#define FIX_SLAVE_ADDR 0
#define SEND_ATONCE 1
#define SENDCOMBINED 0
class T_datif : public QMainWindow
{
Q_OBJECT
char sendINrequestsAutomatic(void);
// sende alle Befehle um die Eingangsdaten abzufragen der Reihe nach
char loadRecDataFromFrame();
void datif_startSending(void);
void datif_sendIOrequest(uint16_t WRcmd, uint16_t RDcmd, uint8_t nrOfWrData);
void datif_send8byteOutCmd(uint16_t WRcmd, uint16_t RDcmd);
bool verifyLineTestresponse(uint8_t RdDlen, uint8_t *receivedData);
void datif_OUT_setTime(void);
uint8_t datif_OUT_SendRandomData(uint8_t *buf, uint8_t Length);
void datif_send64byteOutCmd(uint16_t WRcmd, uint16_t addr, uint16_t RDcmd);
void datif_sendToMemory(uint16_t WRcmd, uint16_t docNr, uint16_t blockNr, uint8_t *data64);
// send printer documents to DC2 memory
// docNr: 0...15(31) with 1280 byte each (20 blocks a 64byte)
// blockNr=0...19 with 64byte each
// docNr =transmitted in WRITEADDRESS high byte
// blockNr=transmitted in WRITEADDRESS low byte
int datif_noResponseCtr;
T_prot *myDCIF;
QTimer *datif_trigger;
uint8_t selectedSlaveAddr;
private slots:
char datif_cycleSend();
void StoredRecData();
public:
T_datif(QWidget *parent = nullptr);
void resetChain(void);
char isPortOpen(void);
void sendWRcommand(uint16_t nxtAsCmd);
// Sende Schreibbefehle die bereits vorher asynchron gespeichert wurden
void send_requests(uint16_t nextWrCmd);
void sendHighLevel(uint16_t nxtHLCmd);
signals:
void ResponseRecieved();
//the requested data are stored in peripheral image
// can be loaded with epi
void datif_templatePrintFinished_OK();
void datif_templatePrintFinished_Err();
void datif_gotNewCoin();
};
#endif // CI_H

202
include/datei.h Normal file
View File

@ -0,0 +1,202 @@
#ifndef DATEI_H
#define DATEI_H
#include <stdint.h>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#include "tslib.h"
#include <QString>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonParseError>
// create csv file with:
#define FILESEPERATOR ','
// pasre csv with:
#define FILESEP1 ','
#define FILESEP2 ';'
#define NEWLINEINFILE '\n'
#define MAXNUMBEROFSEQUENCES 200
// only for csv files
// all generated files located in sudirectory "dynamic machine data - dmd"
#define FILENAME_SHAREDDATA "../dmd/DCshare.csv"
#define FILENAME_SHARED_UID "../dmd/DC_UID.csv"
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ create csv file -------------------------------
// -------------------------------------------------------------------------------------------------
// create array with strings and values (to be written to file)
void csv_startCreatingFile(void);
void csv_addTextToFile(QString myText);
void csv_addIntToFile(int myValue);
void csv_addUintToFile(uint myValue);
void csv_addLongvalToFile(qlonglong myValue);
void csv_addUlongvalToFile(qulonglong myValue);
//void csv_addCurrentTimeToFile(void);
//void csv_addCurrentDateToFile(void);
void csv_addNewlineToFile(void);
QByteArray csv_readbackArray(void);
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ parse csv file -------------------------------
// -------------------------------------------------------------------------------------------------
// return number of entries in the just read file (entries are seperated by
// comma or line-feed)
uint32_t csv_nrOfEntriesInFile(QByteArray readFromFile);
// before: QByteArray sourceFile=datei_readFromFile(filename);
QByteArray csv_getOneFileSequence(QByteArray sourceFile, uint32_t sequNr);
// not needed, just for test // sequNr: 0....(size-1)
// get single entries of of the just read file:
int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr);
// sequNr: 0....(size-1)
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ create Json Record -------------------------------
// -------------------------------------------------------------------------------------------------
void json_startRecord(void);
// clear buffer and write opening curly bracket {
void json_enterIntToRecord(QString attribute, ulong i_value);
// example: "parameter":1234567890
void json_enterTextToRecord(QString attribute, QString txt_value);
// example: "parameter":"slow"
//void json_addCurrentTimeToRecord(QString attribute);
// example: if attribute=myTime: "myTime":"hh_mm_ss"
//void json_addCurrentDateToRecord(QString attribute);
// example: if attribute=myDate: "myDate":"dd.mm.yyyy"
// also / possible as seperator
// further possible forms:
// format= 0: dd.mm.yyyy (deutsch)
// 1: mm.dd.yyyy (amerika)
// 2: yyyy.mm.dd (Iran, Dubai)
// 3: dd.yyyy.mm
// 4: mm.yyyy.dd
// 5: yyyy.dd.mm
void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals);
// add array of numbers with "nrofVals" elements
void json_enterStructToRecord(QString attribute);
// every call must be concluded with an extra "json_finishFile()"
// example: "sname":{
void json_finishStruct(void);
void json_finishRecord(void);
// close curly bracket
QString json_readbackRecordStr(void);
QByteArray json_readbackRecordBa(void);
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ parse Json file -------------------------------
// -------------------------------------------------------------------------------------------------
// first: QByteArray datei_readFromFile(QString filename);
//void datei_json_readTestFile(QString filename);
int json_nrOfPairsInFile(QByteArray filename);
bool json_exists(QByteArray filename, QString searchForKey);
// look for "searchForKey" =name of the pair (left of : )
// retval true if exists
bool json_remove(QByteArray filename, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and remove the record from file
// retval true if removed
QString json_searchForStringInFile(QByteArray filename, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
int json_searchForIntInFile(QByteArray filename, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
//.......................
QJsonObject json_searchForObjectInFile(QByteArray filename, QString searchFor);
// return an object from the json file
int json_nrOfPairsInObject(QJsonObject objname);
QString json_searchForStringInObject(QJsonObject objname, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
int json_searchForIntInObject(QJsonObject objname, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
//.......................
QJsonArray json_searchForArrayInFile(QByteArray filename, QString searchFor);
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
int json_nrOfValuesInArray(QJsonArray arrayname);
bool json_getValuesOfArray(QJsonArray arrayname, int *buf, int MaxBufferSize);
// assuming that the array consists of integers
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ read, write, copy files -------------------
// -------------------------------------------------------------------------------------------------
void datei_closeFile(QString filename);
// read content of an exiting file:
QByteArray datei_readFromFile(QString filename);
bool datei_ifFileExists(QString filename);
char datei_writeToFile(QString filename, QByteArray content);
// retval=0 if successful 1: no write access allowed
// 2:cannot open to append 3:cannot create new file
bool datei_copyFile(QString currentFileName, QString newFileName);
// retval=true if successful
bool datei_clearFile(QString filename);
// retval=true if successful
#endif // DATEI_H

102
include/dcBL.h Normal file
View File

@ -0,0 +1,102 @@
#ifndef DCBL_H
#define DCBL_H
#include <stdint.h>
#include "qbytearray.h"
#include "qstring.h"
#include <QFile>
uint8_t dcBL_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf);
// make BL protocol, retval = outbuf length (5...133)
// bring data in correct form: start always with 0x02 finish with 0x03 and append checksum
// 0x02 Cmd < ...sendData ..> CRC CRC 0x03
// Data length = 0...64
// special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80
// so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64
uint8_t dcBL_readBLversion(uint8_t *sendData);
// minimum size of sendData-buffer: 5byte retval: length
uint8_t dcBL_readFWversion(uint8_t *sendData);
// minimum size of sendData-buffer: 5byte retval: length
uint8_t dcBL_exitBL(uint8_t *sendData);
// minimum size of sendData-buffer: 5byte retval: length
uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData);
// minimum size of sendData-buffer: 13byte retval: length (9...13)
uint8_t dcBL_writeLastPage(uint8_t *sendData);
// minimum size of sendData-buffer: 5byte retval: length
uint8_t dcBL_restartDC(uint8_t *sendData);
// minimum size of sendData-buffer: 20 byte retval: length
uint8_t dcBL_activatBootloader(uint8_t *sendData);
// minimum size of sendData-buffer: 20 byte retval: length
uint8_t dcBL_getResponse(uint8_t *respBuff);
// retval: nr of received bytes
bool dcBL_responseOK();
// retval: 0: response OK (cmd |0x80) 1: response error (cmd or "0xe0")
bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl);
bool dcBL_isTextMemFree(void);
void dcBL_writeText(QString newTxt);
bool dcBL_checkForText(void);
// if pointer at 0 then no more content
QString dcBL_readText(void);
// read from 0...9 (oldest first)
void dcBL_iniChain(void);
uint8_t dcBL_startChain(void);
uint8_t dcBL_runChain(void);
void dcBL_iniLoading(void);
void dcBL_startLoading(void);
uint8_t dcBL_sendHexfile(void);
uint8_t dcBL_getResult(void);
// call after every step to what's going on....
// 1: connected to BL
// 2: transmission started
// 3: transmission successful
#define RAW_BL_DATALEN 150
void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData);
uint8_t epi_getRawReceivedData(uint8_t *receivedData);
// retval=length, will be zeroed after first reading
uint8_t epi_getRawRecLength(void);
// retval=length
QString epi_getRawReceivedString();
void epi_clrRawReceivedString();
uint8_t dcBL_sendSuccess(uint8_t lastCommand);
// return val: 0: no response by now 1:error 10: OK
// lastCommand=0x21 for sendAddr or 0x22 for send data
char dcBL_loadBinary(char withDisplay);
#endif // DCBL_H

1250
include/hwapi.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

126
include/prot.h Normal file
View File

@ -0,0 +1,126 @@
#ifndef SERIAL_FRAME_H
#define SERIAL_FRAME_H
#include <stdint.h>
#include <QMainWindow>
#include <QString>
#include <QTimer>
#include "tslib.h"
#include "com.h"
/*
get's OUT-data from datif,
get's IN-data from datif
get's send command from datif
makes frame and calls: isSerialFree(), setSendData(),
if not free retrigger datif sending period (normally 500ms or 50ms for direct cmds)
with control-signal: gotReceiveData():
getRecData();
send results to diag window/line
send IN-data to datif
*/
#define FRAME_DATALEN 64
#define FRAME_MAXLEN FRAME_DATALEN+20
#define BL_DATA_LEN 150
#define DATALEN_SEND_FAST 4
#define DATALEN_SEND_LONG 64
#define HEADERLEN_SEND 4
#define TELEGRAMLEN_SEND_FAST 12
#define TELEGRAMLEN_SEND_LONG 70
#define STARTSIGN_SEND_FAST 0x3F
#define STARTSIGN_SEND_LONG 0x3D
#define DATALEN_RECEIVE_FAST 8
#define DATALEN_RECEIVE_LONG 64
#define HEADERLEN_RECEIVE 2
#define TELEGRAMLEN_RECEIVE_FAST 12
#define TELEGRAMLEN_RECEIVE_LONG 68
#define STARTSIGN_RECEIVE_FAST 0x5F
#define STARTSIGN_RECEIVE_LONG 0x5D
class T_prot : public QMainWindow
{
Q_OBJECT
// Dateneingang von Datif:
uint8_t SendDataValid; // bit1: WR OK bit 2: RD OK
uint16_t slaveAddr;
uint16_t WriteCommand;
uint16_t WriteAddr;
uint8_t WrDataLength;
uint8_t ui8OutputData[FRAME_DATALEN];
char chOut_Data[FRAME_DATALEN];
uint8_t kindOfData; // 0: binaries, 1:text
uint16_t ReadCommand;
uint16_t ReadAddr;
uint16_t reserve;
// Ausgangs-Daten, werden vom Datif geholt:
// nur wenn CommandState und readState OK
uint8_t RecSlaveAddr;
bool INdataValid; // nur true wenn CommandState OK und readState OK
uint16_t readSource; // diese (Eingangs-)Daten stehen im Puffer
uint16_t readAddress; // von dieser Adr wurden die Daten gelesen
//uint8_t lastWakeSrc; // falls der Slave den Master geweckt hat
uint8_t RdDataLength;
uint8_t InputData[FRAME_DATALEN];
// 11.11.2020:
uint8_t BLsendDataLength;
uint8_t ui8BLsendData[BL_DATA_LEN];
T_com *mySerialPort;
void startPacking(void);
void startFastPacking(void);
uint8_t FramecheckInData(uint8_t *Inbuf, uint16_t LL);
uint8_t FastCheckInData(uint8_t *Inbuf, uint16_t LL);
uint8_t CheckInResult(uint8_t *Inbuf);
uint8_t ShowFastInData(uint8_t *recBuffer);
uint8_t ShowInData(uint8_t *recBuffer); // was CheckInData
void setRecLen(uint16_t WriteCmd);
private slots:
void analyseRecData(void);
public:
T_prot();
bool isPortOpen(void);
bool isSerialFree(void);
void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data);
void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr);
void setUserWriteData(uint16_t WriteCmd);
void setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, char *data);
void setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val);
void setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1);
void setUserReadData( uint16_t ReadCmd, uint16_t RdAddr, uint16_t reserv);
void setUserReadData( uint16_t ReadCmd, uint16_t RdAddr);
void setUserReadData( uint16_t ReadCmd);
void setBLsendData( uint8_t len, uint8_t *buf);
void receiveFixLen(int64_t nrOfbytesToReceive);
void sendUserData(uint16_t slaveAdr);
bool ifDataReceived();
bool getReceivedInData(uint8_t *SlavAddr, uint16_t *readSrc, uint16_t *readAddr,
uint8_t *RdDlen, uint8_t *receivedData);
// retval: data valid, only one time true
signals:
void framerecieved(); //bool gotINdata);
void rawDataRecieved();
};
#endif // T_prot_H

261
include/sendWRcmd.h Normal file
View File

@ -0,0 +1,261 @@
#ifndef SENDWRCMDS_DEFS_H
#define SENDWRCMDS_DEFS_H
#include <stdint.h>
#include "tslib.h"
#include <QString>
// asynch. Commands
// store OUTPUT commands until time to send
// problem: OUT commands are set if a button is pressed or a transaction event happens
// so it's never synchron with sending grid
// but sending must apply the 100ms time grid as we have to wait for the response before sending the next command!!!
// Level 0 (DC direct)
#define SENDDIRCMD_TestSerial 1
#define SENDDIRCMD_MakeReset 2
#define SENDDIRCMD_setTime 3
#define SENDDIRCMD_setWakeFrequ 4
// Level 1 (DC DO's switching connected parts)
#define SENDDIRCMD_MOVEUP_LOCK 5
#define SENDDIRCMD_MOVEDN_LOCK 6
#define SENDDIRCMD_OPENUP_DOOR 7
#define SENDDIRCMD_OPENDN_DOOR 8
#define SENDDIRCMD_LEDILLU 9
#define SENDDIRCMD_LEDCOIN 10
#define SENDDIRCMD_LEDTICKET 11
#define SENDDIRCMD_LEDPAD 12
#define SENDDIRCMD_LEDSTART 13
#define SENDDIRCMD_LEDINSIDE 14
//#define SENDDIRCMD_LED_ALL 15
#define SENDDIRCMD_FAN 16
#define SENDDIRCMD_LAERM 17
#define SENDDIRCMD_REL1 18
#define SENDDIRCMD_WAKEPTU 20
#define SENDDIRCMD_AUXPWR 21
#define SENDDIRCMD_AUXDDR 22
#define SENDDIRCMD_AUXOUT 23
#define SENDDIRCMD_UCONTACT_ON 30
#define SENDDIRCMD_PRN2_SWONOFF 31
#define SENDDIRCMD_MIF_SWONOFF 32 // 0x2900
#define SENDDIRCMD_MIF_ATBCREATE 33 // 0x2907
#define SENDDIRCMD_MOD_SWONOFF 40
#define SENDDIRCMD_MOD_WAKE 41
#define SENDDIRCMD_MDB_POWER 42
#define SENDDIRCMD_MDB_WAKE 43
#define SENDDIRCMD_CRED_ON 44
#define SENDDIRCMD_CRED_WAKE 45
#define SENDDIRCMD_SHUT_MOV 50
#define SENDDIRCMD_ESCRO_MOV 51
#define SENDDIR_OPENVAULT 52
#define SENDDIR_REJMOT_ON 53
#define SENDDIR_REJMOT_RUN 54
// Level 2 (serial from DC to devices)
#define SEND_REQU_SERCONF 100
#define SEND_REQU_HWversion 101
#define SEND_REQU_SWversion 102
#define SEND_REQU_CONDITION 103
#define SEND_REQU_UID 104
#define SEND_REQU_TIME 105
// includes wake frequency
#define SEND_REQU_ANALOGS 110
#define SEND_REQU_DIG_INPUTS 111
#define SEND_REQU_DIG_OUTPUTS 112
#define SEND_REQU_PRN_STATE 120
#define SEND_REQU_PRN_FONTS 121
#define SEND_REQU_PRN_ALL 122
#define SEND_REQU_MIFSTATE 123
// Type and state of reader
#define SEND_REQU_MIFDATA 124
// Type, UID, Header of card
// read one card sector
// sectors must be addressed by RD_ADD
#define SEND_REQU_MIF_ATB_TYPE 125
#define SEND_REQU_MDB_GETSTAT 126
//#define SEND_REQU_MDB_GETWAK 127
#define SEND_REQU_MDB_GETRESP 128
#define SEND_REQU_EMP_GETALL 129
#define SEND_REQU_EMP_GETCOIN 130
#define SENDDIRCMD_DEVICE_PARA 131
#define SENDDIRCMD_MACHINE_ID 132
#define SEND_REQU_DEVICE_PARA 133
#define SEND_REQU_MACINE_ID 134
// further: mdb state, coinchecker state, bill state, modem state, credit_state....
#define SENDDIRCMD_SHUTOPENBYTIME 60
#define SENDDIRCMD_SHUTOPENBYCOIN 61
//#define SENDDIRCMD_SHUT_SENDTIME 62
#define SENDDIRCMD_ESCRO_TAKE 63
#define SENDDIRCMD_ESCRO_GIVE 64
#define SENDDIRCMD_PRN_SYS_CMD 70
#define SENDDIRCMD_PRN_ESC_CMD 71
#define SENDDIRCMD_PRN_SETUP 72
#define SENDDIRCMD_PRN_MOVE 73
#define SENDDIRCMD_PRN_SETFONT 74
#define SENDDIRCMD_PRN_SETLETT 75
#define SENDDIRCMD_PRN_CUT 76
//#define SENDDIRCMD_PRN_TXT // not needed
#define SENDDIRCMD_PRN_LF 78
#define SENDDIRCMD_PRN_FONTTAB 79
#define SENDDIRCMD_PRN_BC 80
#define SENDDIRCMD_PRN_QR 81
#define SENDDIRCMD_PRN_STOREDQR 82
#define SENDDIRCMD_PRN_LOGO_FL 83
//#define SENDDIRCMD_PRN_LOGO_GRAF 84
//#define SENDDIRCMD_PRN_LOGODAT 85
//#define SENDDIRCMD_PRN_STORBC 86
#define SENDDIRCMD_PRN_STORQR 87
#define SENDDIRCMD_PRN_DOC 88
#define SENDDIRCMD_PRN_CLEARDOC 89
//#define SENDDIRCMD_MDB_POWER 42
//#define SENDDIRCMD_MDB_WAKE 43
#define SENDDIRCMD_MDB_RES 90
#define SENDDIRCMD_MDB_SENDCMD 91
#define SENDDIRCMD_MDB_SNDMSG 92
#define SENDDIRCMD_EMP_SETT 93
#define SENDDIRCMD_EMP_POLL 94
#define SENDDIRCMD_EMP_STARPPAY 95
#define SENDDIRCMD_EMP_STOPPAY 96
// obsolete:
#define SENDDIRCMD_PRN1_SENDTEXT 54
#define SENDDIRCMD_PRN1_SENDCMD 55
#define SENDDIRCMD_PRN1_SERPAR 56
#define SENDDIRCMD_PRN_LEVEL2_4B 58
#define SENDDIRCMD_PRN_LEVEL2_64 59
// highest priority
#define CMDSTACKDEPTH 16
// means: up to 16 cmd can be stored. They are issued one by one every 100ms
void sendWRcmd_clrCmdStack(void);
bool sendWRcmd_setSendCommand0(uint16_t nextCmd);
// GUI or app sends a command to DC transfered by serial
uint16_t sendWRcmd_getSendCommand0(void);
// lower priority
#define CMD4STACKDEPTH 8
void sendWRcmd_clrCmd4Stack(void);
bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4);
#define CMD8STACKDEPTH 4
void sendWRcmd_clrCmd8Stack(void);
bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4);
uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4);
// lowest priority
// wait for resonse before send next!
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf);
uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf);
// retval = *leng
void sendWRcmd_INI(void);
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf);
// HWapi writes data to be forwarded to DC and further to mdb-device
// not batched! don't use twice within 100ms
uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf);
// datif reads data to forward to dc
// ONE printer doc consists of 20 x 64 byte
#define MAXNROF_PRNBYTES 64
#define MAXNROF_PRNBLOCKS 20
void epi_resetPrinterStack(void);
uint8_t epi_storePrnText(char *buf, uint8_t leng);
// store text and binary data from Gui in next higher free memory 0....9
uint8_t gpi_restorePrnText(uint8_t *retbuf);
// read printer text and send to slave, size of retbuf== 64
uint8_t gpi_chk4remainingText(void);
// retval: 0: no more textline left (to send) >0: nr of lines
void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 );
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4);
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
#define FDCMD_STACKDEPTH 16
void sendFDcmd_clrStack(void);
bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
// write Command to memory, wait for transport
bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4);
uint8_t check4FDshortCmd(void);
// returns number of waiting command, maxFDCMD_STACKDEPTH
uint8_t checkNextFDcmd(void);
// return 0: no command waiting
// 1: short cmd
// 2: long cmd
uint8_t check4freeFDshortCmd(void);
// returns number of free places in short-command stack
//#define FDLONG_STACKDEPTH 16
//void longFDcmd_clrStack(void);
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data);
// write Command to memory, wait for transport
// data buffer size always 64! data[64], padded with 0
//bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data);
bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data);
//uint8_t check4FDlongCmd(void);
// returns number of waiting command
//uint8_t check4freeFDlongCmd(void);
// returns number of free places in long-command stack
uint8_t epi_store64BdevParameter(uint8_t length, uint8_t *buf);
// HWapi writes data to be stored
uint8_t epi_restore64BdevParameter(uint8_t *length, uint8_t *buf);
#endif

301
include/shared_mem_buffer.h Normal file
View File

@ -0,0 +1,301 @@
#ifndef SHARED_MEM_BUFFER_INCLUDED_H
#define SHARED_MEM_BUFFER_INCLUDED_H
#include <cinttypes>
#include <atomic>
#include <QSharedMemory>
struct SharedMemBuffer {
struct rs {
char comportName[16]; // z.B. "COM48"
char baudStr[16]; // z.B. "19200"
int baudNr; // 0...5 oder -1
uint8_t connect; // 0,1
bool portIsOpen;
} rs;
char AutoEmissionOn; // 1: zyklisch Anfragen zum Slave senden
struct datif {
uint16_t sendingPeriod;
bool sendingPer_changed;
} datif;
#if 0
// controlBus.cpp
char txt4comStateLine[32];
char txt4HsStateLine[32];
char txt4masterStateLine[32];
char txt4resultStateLine[32];
char txt4dataLine[32];
char txt4datifReceive[32];
char txt4diagWindow[32];
char sndTxt4diagWindow[32];
bool Sdata_serialTestResult[32];
uint8_t Sdata_pProtResultOk[32];
uint16_t Sdata_receivedDataLength[32];
uint8_t Sdata_receivedDataBlock[64];
// datif.cpp
uint8_t dif_dataStep;
uint8_t dif_scanStep;
uint8_t RDBLKNR;
uint8_t datif_OutCmdpara1;
uint8_t datif_OutCmdpara2;
uint8_t datif_OutCmdpara3;
uint8_t datif_OutCmdpara4;
uint16_t datif_OutCmdpara5;
uint32_t datif_OutCmdpara6;
uint8_t cycl_running;
// dcBL.cpp
uint8_t dcBL_LastBLcmd; // stored the last sent cmd in order to analys response
uint8_t dcBL_AtbBinFile[300000];
uint32_t dcBL_fileSize;
uint16_t dcBL_nrOfBlocks;
uint16_t dcBL_fileCrc;
uint8_t dcBL_myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise
char BlResp[50][32];
uint8_t dcBL_step;
uint8_t dcBL_state;
uint16_t dcBL_BlkCtr;
uint16_t dcBL_cyclCtr;
uint16_t repeatCtr;
uint8_t Sdata_rawData[150];
uint8_t Sdata_LengthRawData;
// hwapi.cpp
uint16_t hwapi_shutterTime;
char ticketTemplate[1024];
// sendWRcmd.cpp
uint16_t nextAsynchsendCmd0[16];
uint8_t nrOfCmdsInQueue;
uint16_t nextAsynchsendCmd4[8];
uint8_t nextCmd4para1[8];
uint8_t nextCmd4para2[8];
uint8_t nextCmd4para3[8];
uint8_t nextCmd4para4[8];
uint8_t nrOfCmds4InQueue;
uint16_t nextAsynchsendCmd8[4];
uint8_t nextCmd8para1[4];
uint8_t nextCmd8para2[4];
uint16_t nextCmd8para3[4];
uint32_t nextCmd8para4[4];
uint8_t nrOfCmds8InQueue;
uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer
uint8_t sendAsyDatLen;
uint8_t Sdata_mdbSendBuffer[64];
uint8_t Sdata_mdbSendLen;
uint8_t prnDataParameters[4];
uint8_t prnDataBufferUser;
char Sdata_PRN_TEXT[20][64];
uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK
uint8_t nextFDwrCmd[16];
uint8_t nextFDrdCmd[16];
uint8_t nextFDblkNr[16];
uint8_t nextFDpara1[16];
uint8_t nextFDpara2[16];
uint8_t nextFDpara3[16];
uint8_t nextFDpara4[16];
uint8_t p_nextFDcmdsInQueue;
uint8_t longFDwrCmd[16];
uint8_t longFDrdCmd[16];
uint8_t longFDblkNr[16];
uint8_t longFDlength[16];
uint8_t longFDpara[16][64];
uint8_t p_longFDcmdsInQueue;
// storeInData.cpp
bool indat_savePrnPwr;
bool indat_saveMifPwr;
bool indat_MdbIsOn;
#endif
uint8_t ndbs;
uint8_t pari;
uint8_t nsb;
uint8_t br;
#define MAXNROF_GENSTR 16
char genStrings[MAXNROF_GENSTR][64];
#define MAXNROF_AI 4
uint16_t AI_val[MAXNROF_AI];
struct DigitalInputs {
uint8_t doorSwitch;
uint8_t vaultSwitch;
uint8_t lockSwitch;
uint8_t opto;
uint8_t aux;
bool wakeFromPtu;
bool wakeFromMdb;
bool wakeFromModem;
bool PrnReady;
bool CoinAttach;
bool CoinEscrowOpen;
bool mifCardTap;
bool contactPwrOn;
bool mifarePwrOn;
bool rdbk_mdbTxd;
bool AuxPwrOn;
bool gsmPwrOn;
bool creditPwrOn;
bool printerPwrOn;
bool mdbPwrOn;
bool rejMot_home;
uint8_t npe_sensor;
} din;
struct DigitalOutputs {
uint8_t mbdRxTst;
uint8_t motorBits;
uint8_t serialSwitch; // serial drv on/off, Serial mux1, Serial mux2
uint8_t ledsAndFan;
uint8_t laermUndRelay;
uint8_t ptuWake;
uint8_t auxPower;
uint8_t coinShutter;
uint8_t coinEscrow;
uint8_t printerPower;
} dout;
struct Sdata {
#define NROFMIFSTATEBYTES 40
#define PRN_STATE_ARRAY_SIZE 20
#define PRN_STATE_FONT_SIZE 20
uint8_t MIF_STATE[NROFMIFSTATEBYTES];
uint8_t MIF_DATA[12][64];
uint8_t PRN_STATE[PRN_STATE_ARRAY_SIZE];
uint8_t PRN_FONTS[PRN_STATE_FONT_SIZE];
bool mdb_busRdy;
bool mdb_V12on;
bool mdb_V5on;
uint8_t mdbNrOfRecData;
uint8_t RecBuff[40];
uint8_t empNrOfsettings;
uint8_t emp_settingsBuff[66];
uint8_t NrOfDeviceSetting;
uint8_t DeviceSettingBuff[66];
uint8_t NrOfMachineIDSetting;
uint8_t NrOfMachineIDBuff[66];
uint64_t slaveUID;
uint8_t UIDstr[8];
#define MAXNROF_MEASURE 4
uint32_t measurement[MAXNROF_MEASURE];
bool serialTestResult;
uint8_t pProtResultOk;
uint16_t receivedDataLength;
uint8_t receivedDataBlock[64];
} Sdata;
uint8_t mif_cardType;
uint8_t mif_cardHolder[8];
#if 0
#define MEMDEPTH_GOTCOINS (16)
struct T_coin {
uint8_t valid;
uint8_t signal;
uint8_t error;
uint8_t pad;
uint16_t value;
} gotCoin[MEMDEPTH_GOTCOINS];
uint8_t ctr_gotCoin;
#endif
struct store {
uint32_t insertedAmount;
uint16_t lastCoinType[64];
uint16_t lastCoinValue[64];
uint64_t wakeSrc;
uint8_t rbDevParamLen;
uint8_t rbDevParams[66];
uint8_t deviceCondLen;
uint8_t deviceCond[66];
uint8_t machCondLen;
uint8_t machCond[66];
uint8_t DcBackupNrOfAccNr;
uint16_t DcBackupAccNr[16]; // z.Z. nur 8
uint8_t gotNrBlocksOfVaultRec;
uint8_t vaultrecord[360];
uint32_t amount;
uint16_t nrOfCoins;
} store;
struct T_globTime {
// Reihenfolge nicht vertauschen!!!!!
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t Year;
uint8_t Month;
uint8_t DayOfMonth;
uint8_t DayOfWeek; // 1=monday...7
uint8_t reserve1;
uint16_t MinutesOfToday;
uint16_t reserve2;
uint32_t SecondsOfToday;
uint8_t IsLeapyear;
uint8_t nextLeap;
uint8_t lastLeap;
uint8_t hoursOfWeek;
uint16_t minOfWeek;
uint16_t hoursOfMonth;
uint16_t minOfMonth;
uint16_t dayOfYear;
uint16_t hoursOfYear;
uint16_t reserve3;
uint32_t minOfYear;
uint8_t squareOutMode;
uint8_t free1;
uint16_t reserve4;
uint32_t minOfMillenium;
// bis hierher 44byts
uint32_t free2;
uint32_t free3;
uint32_t free4;
} getGlobalTime;
static QSharedMemory *getShm(std::size_t s = 0);
static SharedMemBuffer *getData() {
return (SharedMemBuffer *)getShm()->data();
}
static SharedMemBuffer const *getDataConst() {
return (SharedMemBuffer const *)getShm()->data();
}
#if 0
static std::atomic<bool> __sharedMemLocked;
static bool sharedMemLocked() {
return __sharedMemLocked;
}
static void setSharedMemLocked() {
__sharedMemLocked = true;
}
static void setSharedMemUnlocked() {
__sharedMemLocked = false;
}
#endif
};
#endif // SHARED_MEM_BUFFER_INCLUDED_H

577
include/storeINdata.h Normal file
View File

@ -0,0 +1,577 @@
#ifndef STOREINDATA_H
#define STOREINDATA_H
#include <stdint.h>
#include "tslib.h"
#include <QString>
#define MAXNROF_AO 3
#define MAXNROF_GENSTR 16
#define MAXNROF_CONTR_PORTS 11
#define MAXNROF_DIports 2
#define MAXNROF_DOports 2
#define MAXNROF_CTR 2
#define MEASCHAN_TEMPERATURE 0
#define MEASCHAN_VOLTAGE 1
// gpi: DC-driver stores data for graphic peripheral interface
// epi: gui reads values from external peripheral interface
// store power on/off condition of the devices to control the data request
void indat_storePrinterPower(bool isOn);
bool indat_isPrinterOn();
void indat_storeMifarePower(bool isOn);
bool indat_isMifareOn();
void indat_storeMDBisOn(bool isOn);
bool indat_isMdbOn();
void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits,
uint8_t parity, uint8_t NrStopBits);
void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits,
uint8_t *parity, uint8_t *NrStopBits);
QString epi_getSlaveParamSTR();
void gpi_storeGenerals(uint8_t genNr, QString text);
// 0=HW 1=SW 2=State
QString epi_loadGenerals(uint8_t genNr);
// genNr=0=HW 1=SW 2=State
void gpi_storeUID(uint8_t const *buf8byteUid);
//void gpi_storeUID(uint8_t *buf8byteUid);
// buffer size: 8 byte
void epi_getUIDdec(uint8_t *buf8byteUid);
// buffer size: 8 byte
QString epi_getUIDstr();
// ///////////////////////////////////////////////////////////////////////////////////
// Time and Date
// ///////////////////////////////////////////////////////////////////////////////////
uint8_t epi_getSquareMode();
void gpi_backupSquareMode(uint8_t squMode);
void gpi_backupTime(uint8_t *timeBuffer, uint8_t Leng); // 104, <=8byte
void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss);
void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd);
void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday);
bool epi_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear);
bool epi_isLeapYear();
void epi_getSpecialWeekTimeDate(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek);
void epi_getSpecialMonthTimeDate(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth);
void epi_getSpecialYearTimeDate(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear);
// ///////////////////////////////////////////////////////////////////////////////////
// Analog values
// ///////////////////////////////////////////////////////////////////////////////////
#define MAXNROF_AI 4
void gpi_storeAIs(uint8_t aiNr, uint16_t val); // rs -> Sdata
uint8_t gpi_getMaxNrAIs();
uint16_t epi_loadAIs(uint8_t aiNr); // Sdata -> gui
// return value of one ADC with channel nr: aiNr 0...15
uint32_t epi_loadMeasureValue(uint8_t ValueNr);
// ValueNr 0=ADC0, 1=ADC1 aso...
void gpi_storeMeasureValue(uint8_t ValueNr, uint32_t val);
// in mV, also bis 65,535V
QString epi_getSlaveTemperatureStr();
QString epi_getSlaveVoltageStr();
// value in "meas_volt" in mV, also bis 65,535V. Value range [6000...16000] (6V...16V)
// ///////////////////////////////////////////////////////////////////////////////////
// digital inputs
// ///////////////////////////////////////////////////////////////////////////////////
void gpi_storeDI_doorSwitches(uint8_t upperDoor, uint8_t lowerDoor, uint8_t vaultDoor);
uint8_t epi_getDI_doorSwitches(void);
// bit0: upper door 1: low door 2:vault door
void gpi_storeDI_vaultSwitches(uint8_t CashBoxIn, uint8_t BillBoxIn);
uint8_t epi_getDI_vaultSwitches(void);
// bit0: cash box 1: bill box in
void gpi_storeDI_lockSwitches(uint8_t indatUL, uint8_t indatLL);
// D5: bit 0: upper lockbar up bit1:down
// D6: bit 0: lower lockbar up bit1:down
uint8_t epi_getDI_lockSwitches(void);
// retval: bit 0: upper lockbar up bit1: upper lockbar is down
// bit 2: lower lockbar up bit1: lower lockbar is down
void gpi_storeDI_optos(uint8_t indatOpto);
// OptoIn bit 0,1: optoin 1,2
uint8_t epi_getDI_optos(void);
// bit0: opto in 1 1: opto in 2
void gpi_storeDI_auxIn(uint8_t indatAuxIn);
// Aux0...5
uint8_t epi_getDI_auxIn(void);
// bit0: auxin 1 ... 5: auxin 6
void gpi_storeDI_ptuWake(uint8_t indat);
bool epi_getDI_ptuWake(void);
void gpi_storeDI_mbdWake(uint8_t indat);
bool epi_getDI_mdbWake(void);
void gpi_storeDI_prnReady(uint8_t indat);
bool epi_getDI_prnReady(void);
void gpi_storeDI_CoinAttach(uint8_t indat);
bool epi_getDI_CoinAttach(void);
void gpi_storeDI_CoinEscrow(uint8_t indat);
bool epi_getDI_CoinEscrow(void);
void gpi_storeDI_mifareCardTapped(uint8_t indat);
bool epi_getDI_mifareCardTapped(void);
void gpi_storeDI_modemWake(uint8_t indat);
bool epi_getDI_modemWake(void);
void gpi_storeDI_contactPowerIsOn(bool di_contact_PwrOn);
bool epi_getDI_contactPwr(void);
void gpi_storeDI_MifarePowerIsOn(bool di_mifare_PwrOn);
bool epi_getDI_mifarePwr(void);
void gpi_storeDI_readbackMdbTxD(bool di_rdbkMdbTxd);
bool epi_getDI_mdbTxd(void);
void gpi_storeDI_AuxPowerIsOn(bool di_Aux_PwrOn);
bool epi_getDI_auxPwr(void);
void gpi_storeDI_GsmPowerIsOn(bool di_gsm_PwrOn);
bool epi_getDI_gsmPwr(void);
void gpi_storeDI_CreditPowerIsOn(bool di_credit_PwrOn);
bool epi_getDI_creditPwr(void);
void gpi_storeDI_PrinterPowerIsOn(bool di_printer_PwrOn);
bool epi_getDI_printerPwr(void);
void gpi_storeDI_MdbPowerIsOn(bool di_mdb_PwrOn);
bool epi_getDI_mdbPwr(void);
void gpi_storeDI_rejMot_home(bool di);
bool epi_getDI_rejectMotor_homepos(void);
void gpi_storeDI_paperLow(uint8_t di);
uint8_t epi_getDI_npe_sensor(void);
// 0: Sensor sees paper 1: no paper 99: off
// ///////////////////////////////////////////////////////////////////////////////////
// readback digital outputs
// ///////////////////////////////////////////////////////////////////////////////////
void gpi_storeDO_mdbRxTst(uint8_t do_mbdRxTst);
bool epi_getDO_mdbRxTestOut(void);
void gpi_storeDO_motorOutputs(uint8_t Pwr);
uint8_t epi_getDO_motorOuts(void);
// bit0: upper lock forward bit 1 backward
// bit2: lower lock forward bit 3 backward
void gpi_storeDO_serialSwitch(uint8_t state);
// serial drv on/off, Serial mux1, Serial mux2
uint8_t epi_getDO_serialSwitch(void);
// serial drv on/off, Serial mux1, Serial mux2
bool epi_getDO_serialDriverIsOn(void);
bool epi_getDO_serialMux1isSetToPrinter(void);
// mux1 off: serial is switched to printer
bool epi_getDO_serialMux1isSetToModem(void);
// mux1 on: serial is switched to modem
bool epi_getDO_serialMux2isSetToCredit(void);
// mux2 off: serial is switched to credit card terminal
bool epi_getDO_serialMux2isSetToMifare(void);
// mux2 on: serial is switched to mifare reader
void gpi_storeDO_ledsAndFan(uint8_t ledState);
bool epi_getDO_led_coin(void);
bool epi_getDO_led_front(void);
bool epi_getDO_led_ticket(void);
bool epi_getDO_led_pin(void);
bool epi_getDO_led_start(void);
bool epi_getDO_led_inside(void);
bool epi_getDO_fan(void);
void gpi_storeDO_sirenAndRelay(uint8_t sirenRelay);
bool epi_getDO_sirene(void);
bool epi_getDO_relay(void);
void gpi_storeDO_ptuWake(uint8_t state);
bool epi_getDO_ptuWake(void);
void gpi_storeDO_auxPower(uint8_t pwr);
bool epi_getDO_auxPower(void);
void gpi_storeDO_coinShutter(uint8_t state);
bool epi_getDO_coinShutterOpen(void);
bool epi_getDO_coinShutterTest(void);
void gpi_storeDO_coinEscrow(uint8_t state);
uint8_t epi_getDO_coinEscrow(void);
// retval: 1:return flap is open 2:take flap is open 0:closed
void gpi_storeDO_printerPwrOn(uint8_t state);
uint8_t epi_getDO_printerPwr(void);
// ---------------------------------------------------------------------------------------------
// counterchecks, make sure that DC-outputs are correct
/*
bool epi_cntchk_wakePtu(void);
bool epi_cntchk_enabDrv01(void); // no communication possible if 0 !!!!!
bool epi_cntchk_swRs1toModem(void);
bool epi_cntchk_modemWake(void);
bool epi_cntchk_enabDrv2(void);
bool epi_cntchk_swRs2toMIF(void);
bool epi_cntchk_shutterIsOpen(void);
// counter check if shutter is really open, PJ4 must be OUT and HIGH, PB5 must be OUT and HIGH
// retval TRUE: shutter is open FALSE: shutter is closed
bool epi_cntchk_escrowReturnIsOpen(void);
bool epi_cntchk_escrowTakeIsOpen(void);
bool epi_cntchk_aux1DirOut(uint8_t auxNr);
bool epi_cntchk_aux1OutHigh(uint8_t auxNr);
bool epi_cntchk_ledPaperOn(void);
bool epi_cntchk_ledPinpadOn(void);
bool epi_cntchk_ledStartOn(void);
bool epi_cntchk_ledServiceOn(void);
bool epi_cntchk_ledCoinOn(void);
bool epi_cntchk_ledIllumOn(void);
bool epi_cntchk_FanOn(void);
bool epi_cntchk_RelaisOn(void);
bool epi_cntchk_LaermOn(void);
bool epi_cntchk_Mot1Ron(void);
bool epi_cntchk_Mot1Fon(void);
bool epi_cntchk_Mot2Ron(void);
bool epi_cntchk_Mot2Fon(void);
*/
// ------------------------------------------------------------------------------------
// MDB Sendind Data are store here for next transport to DC (Device Controller)
// Transport to Slave runs every 100ms, answer from mdb-slave (e.g. coin changer) comes right
// with next slave answer
// start with: SENDDIRCMD_EXCHGMDB,
// send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms
uint8_t gpi_storeMdbRecData(uint8_t length, uint8_t *buf);
// datif store received mdb data
uint8_t epi_getMdbResponse(void);
// 0=no response 1=ACK 2=NAK 3=ACK with data
uint8_t epi_getMdbRecLength(void);
// 0...31
uint8_t epi_restoreMdbRecData(uint8_t *buf);
// hwapi reads received mdb data from PI
uint8_t gpi_storeMifReaderStateAndCardType(uint8_t *buf);
/* data description:
byte 0: current read state: 0=power off 1=reader-fault 2=ready
3=just reading 4=read complete
5=read partial, removed too early
6=state unknown
byte 1,2: read data length from card
3: 1=reader is OK (reported serial nr is OK) 0=wrong or no reader
4...15: reader version, expected "SL025-1.8"
byte16: 1=card is present 0:not
17: 0
18: card type reported from reader
19: 1=allowed card type 0=not
20: card size: 1 or 4 (dec) = card size
21: LengthOfUID: 4 or 7 (dec) (byte)
22: UID 8 byte in hex
byte 30: sector logged: 0
byte 31: current sector: 0
byte 32: result, always 0
*/
uint8_t epi_restoreMifState(uint8_t *buf, uint8_t maxBufferSize);
// retval 0=OK 1=error host buffer too small
void gpi_storeMifCardData(uint8_t blkNr, uint8_t *receivedData);
// blkNr=0...11 receivedData[64]
uint8_t epi_restoreMifData(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize);
// blkNr=0...11 return buf[64]
// retval: 1=error 0=OK
#define pi_prnStateArraySize 20
#define pi_prnFontArraySize 20
void epi_restorePrinterState(uint8_t *buf);
void gpi_storePrinterState(uint8_t *buf);
void epi_restorePrinterFonts(uint8_t *buf);
void gpi_storePrinterFonts(uint8_t *buf);
void gpi_storeMdbState(uint8_t busReady, uint8_t V12on, uint8_t V5on );
bool epi_restoreMdbBusReady(void);
bool epi_restoreMdbV12Ready(void);
bool epi_restoreMdbV5Ready(void);
void gpi_storeMdbResponse(uint8_t leng, uint8_t *data);
void epi_restoreMdbResponse(uint8_t *leng, uint8_t *data);
// last received mdb answer (from mdb device)
// only needed if a special command was sent directly
// DB0: mdb Device-Nr
// DB1: last sent mdb command
// DB2: nr of received (payload) data bytes (apart from ACK, can be 0....34)
// DB3...DB38: rec.data (payload)
void gpi_storeEmpSettings(uint8_t leng, uint8_t *data);
void epi_restoreEmpSettings(uint8_t *leng, uint8_t *data);
/*
void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data);
void epi_restoreEmpCoinSignal(uint8_t *leng, uint8_t *data);
// return 5 byte:
// data[0]=got coin 0xFF=emp reported an error 0=got nothing
// data[1]=emp-signal of last inserted coin
// data[2,3]=emp-value of last inserted coin
// data[4] = emp-error or warning
void epi_clearEmpCoinSignal();
*/
#define MEMDEPTH_GOTCOINS 16
void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data);
uint8_t epi_isNewCoinLeft(void);
// retval: 0...16 coins left in FIFO
void epi_restoreEmpCoinSignal(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value);
void gpi_storeRbDeviceSettings(uint8_t leng, uint8_t *data);
void epi_restoreRbDeviceSettings(uint8_t *leng, uint8_t *data);
void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data);
void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data);
void epi_clearCurrentPayment(void);
void gpi_storeCurrentPayment(uint32_t insertedAmount, uint16_t lastCoinType, uint16_t lastCoinValue);
uint32_t epi_CurrentPaymentGetAmount(void);
uint16_t epi_CurrentPaymentGetLastCoin(void);
bool epi_CurrentPaymentGetAllCoins(uint16_t *types, uint16_t *values);
// alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert falls die jmd. braucht
void gpi_storeWakeSources(uint8_t *receivedData);
uint64_t epi_getWakeSources(void);
uint8_t epi_getWakeReason(void);
void gpi_storeExtendedTime(uint8_t leng, uint8_t *data);
void epi_restoreExtendedTime(uint8_t *leng, uint8_t *data);
void gpi_storeDeviceConditions(uint8_t leng, uint8_t *data);
void epi_restoreDeviceConditions(uint8_t *leng, uint8_t *data);
void gpi_storeDynMachineConditions(uint8_t leng, uint8_t *data);
void epi_restoreDynMachineConditions(uint8_t *leng, uint8_t *data);
void gpi_storeDCbackupAccNr(uint8_t leng, uint8_t *data);
void epi_restoreDCbackupAccNr(uint8_t *leng, uint16_t *accNrs);
// return accNrs[0..7]
void epi_iniVRstorage(void);
void gpi_storeVaultRecord(uint8_t blkNr, uint8_t *data );
bool epi_checkIfVaultRecordAvailable(void);
bool epi_restoreVaultRecord(uint16_t *length, uint8_t *buf );
// true if completly received
void gpi_storeCBlevel(uint32_t amount, uint16_t nrOfCoins );
uint32_t epi_getCashBoxContent(void);
uint16_t epi_getNrOfCoinsInCashBox(void);
void gpi_storeNewMifareCard(uint8_t typ, uint8_t *holder );
uint8_t epi_mifGetCardType(uint8_t *holder);
//holder[8] = name of card holder
// retval Type of MifareCard, 1=upper door, 2=lower door 3=test printer 4=test coins
void gpi_storeDcDataValid(bool isVal);
bool epi_areDcDataValid();
void epi_clearDynData(void);
void gpi_storeDynData(uint8_t *DCdynDat);
// buffer size: 64 byte
bool epi_getDynPrnData(uint8_t *DCdynDat);
// buffer size: 64 byte
// return true if data are new and valid
#endif

90
include/tslib.h Normal file
View File

@ -0,0 +1,90 @@
#ifndef TSLIB_H
#define TSLIB_H
#include <stdint.h>
#include <QByteArray>
#define LOWBYTE false
#define HIGHBYTE true
uint16_t uchar2uint(char Highbyte, char Lowbyte);
uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte);
uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte);
uint8_t uint2uchar(uint16_t uival, bool getHighB);
uint8_t ulong2uchar(uint32_t ulval, uint8_t getBytNr);
// getBytNr: 0=LSB 3=MSB
void delay(uint16_t MilliSec);
#define MITSEK 1
#define OHNESEK 0
#define HourSys12h 1
#define HourSys24h 0
void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf);
// generate time as ascii string from integers hours/minutes/seconds
// System12h=0: 24h system =1: 12h System
// ShowSec=0: String has 5 digits (hh:mm) =1: String has 8 digits (hh:mm:ss)
// return String in *buf // 12 byte für buf!
#define DateFormatDeutsch 0
#define DateFormatAmerica 1
#define UsePointSeperator 0
#define UseSlashSeperator 1
void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf);
// generate date as ascii string from integers day/month/year
// yearhigh in europe always 20 (not in arabia)
// format= 0: dd.mm.yyyy (deutsch)
// 1: mm.dd.yyyy (amerika)
// 2: yyyy.mm.dd (Iran, Dubai)
// 3: dd.yyyy.mm
// 4: mm.yyyy.dd
// 5: yyyy.dd.mm
// sep: 0: use . as seperator 1: use / as seperator
// return String in *buf // 11 byte für buf!
void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf);
// generate date as ascii string from integers day/month/year
// format= 0: dd.mm.yy (deutsch)
// 1: mm.dd.yy (amerika)
// 2: yy.mm.dd (Iran, Dubai)
// 3: dd.yy.mm
// 4: mm.yy.dd
// 5: yy.dd.mm
// sep: 0: use . as seperator 1: use / as seperator
// return String in *buf // 11byte für buf!
uint16_t tslib_strlen(char *buf);
uint16_t tslib_strlen(uint8_t *buf);
void tslib_strclr(char *buf, char clrsign, uint16_t len);
void tslib_strclr(uint8_t *buf, char clrsign, uint16_t len);
void tslib_strcpy(char *srcbuf, char *destbuf, uint16_t len);
void tslib_strcpy(char *srcbuf, uint8_t *destbuf, uint16_t len);
void tslib_strcpy(uint8_t *srcbuf, uint8_t *destbuf, uint16_t len);
uint16_t tslib_calcCrcCcitt(uint16_t BufLength, uint8_t *buf);
bool tslib_isDecAsciiNumber(char sign);
bool tslib_isHexAsciiNumber(char sign);
int tslib_getMinimum(int val1, int val2);
void tslib_text2array(QByteArray text, char *aray, uint16_t maxArayLen);
// usage: tslib_text2array("my text", ctmp, 50);
void biox_CopyBlock(uint8_t *src, uint16_t srcPos, uint8_t *dest, uint16_t destPos, uint16_t len);
// both buffers starting from pos 0
#endif // TSLIB_H

1758
plugins/interfaces.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
#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

File diff suppressed because it is too large Load Diff

View File

@ -1,195 +0,0 @@
#ifndef ATBDEVICECONTROLLERPLUGIN_H
#define ATBDEVICECONTROLLERPLUGIN_H
#include <QObject>
#include <QLocale>
#include "src/ATBAPP/DeviceControllerInterface.h"
#include "src/ATBAPP/ATBAPPplugin.h"
#include "src/ATBAPP/DeviceControllerDiag.h"
#include "src/ATBAPP/support/Ticket.h"
#include "version.h"
#include "support/PersistentData.h"
#include <DeviceController/interfaces.h>
#include <unistd.h>
class DBusControllerInterface;
class QTextCodec;
using namespace nsDeviceControllerInterface;
class QSettings;
class ATBDeviceControllerPlugin :
public DeviceControllerInterface
{
Q_OBJECT
Q_INTERFACES(ATBAPPplugin)
Q_INTERFACES(DeviceControllerInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA( IID "ATBDeviceControllerPlugin" )
#endif
public:
explicit ATBDeviceControllerPlugin(QObject *parent = nullptr);
~ATBDeviceControllerPlugin();
// ----------------------------------------------------------------------------
// interface:
PLUGIN_STATE initDCPlugin(QObject *eventReceiver, const QSettings & settings);
void sendDeviceParameter(const QJsonObject & jsonObject);
// TASKS: Cash handling -------------------------------------------------------
void requestStartCashInput(const QString & amount);
void requestStopCashInput();
void cashCollect();
void cashCollect(const QString & amount);
void cashAbort();
// read coin/cash processing variants -----------------------------------------
nsDeviceControllerInterface::COIN_PROCESSOR coinProcessor();
nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor();
// TASKS: printing ------------------------------------------------------------
void requestPrintTicket(const QHash<QString, QVariant> & printingData);
void requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash<QString, QVariant> & printingData);
void requestPrintReceipt(const QHash<QString, QVariant> & printingData);
void requestPrintReceipt(const QString & printingString);
// TASKS: Account -------------------------------------------------------------
void requestAccount();
// mandantory ATBAPP plugin methods: ------------------------------------------
nsDeviceControllerInterface::PLUGIN_STATE getState();
QString & getLastError();
const QString & getLastErrorDescription();
const QString & getPluginInfo();
// helpers e.g. for debug / log
const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState);;
public slots:
void onChangedProgramModeToSELL();
void onChangedProgramModeToSERVICE();
void onChangedProgramModeToIDLE();
void onChangedProgramModeToOOO();
void startPhysicalLayer();
void stopPhysicalLayer();
void reboot();
void reset();
signals:
// public Signals are defined in interface
private:
QString errorCode;
QString errorDescription;
QString pluginInfo;
QString serialPortName;
bool useDebug;
bool isMaster;
PLUGIN_STATE pluginState;
QObject* eventReceiver;
DBusControllerInterface* dbus;
hwinf* hw;
DeviceControllerDiag* diag;
PersistentData *persistentData;
uint32_t cashStartAmountInt;
QTextCodec *codec;
bool private_loadCashAgentLib(QString pluginName);
quint8 currentSelectedTicketType;
nsDeviceControllerInterface::CASH_STATE currentCashState;
// counts failed hw->log_chkIfVaultRecordAvailable()
int accountCheckCounter;
// counts faild hw->prn-getPrintResult()
int printResultCheckCounter;
// dbus
int init_sc_dbus();
// printer privates ----------------------------------------------------------------------------
Ticket * currentTicket;
QLocale printerLocale;
void prepareDynTemplateData();
void private_setupDynTemplateData_START_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_STOP_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_FOOD_STAMP(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_FINE_PAYMENT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_FREE_TICKET(struct T_dynDat *dynTicketData, Ticket *ticket);
// ---------------------------------------------------------------------------------------------
private slots:
// printer
void onPrinterDataPrepared();
void onPrinterDataPreparedForTemplates();
void onPrinterPrintNextTemplate();
void onPrinterWaitForPrintingTicket();
void onPrinterWaitForPrintingReceipt();
void onPrinterPrepareDynTemplateData();
void onPrintFinishedOK();
void onPrintFinishedERR();
// cash payment
void onCashGotCoin();
void onCashPayStopedSuccess();
void onCashPayStopByMax();
void onCashPayStopByPushbutton();
void onCashPayStopByEscrow();
void onCashPayStopByError();
void onCashPayStopByTimeout();
void onCashChangerState();
// doors and hardware contacts
void onServiceDoorOpened();
void onVaultDoorOpened();
void onCoinBoxRemoved();
void onCoinBoxInserted();
void onAllDoorsClosed();
void onCBinAndAllDoorsClosed();
// account handling
void private_startAccount();
void private_checkAccountData();
void private_getAccountData();
// measurement values
void onNewVoltage(uint32_t voltage);
void onWokeUp(uchar source);
};
#endif // ATBDEVICECONTROLLERPLUGIN_H

View File

@ -1,25 +0,0 @@
#include "src/ATBAPP/ATBHealthEvent.h"
ATBHealthEvent::ATBHealthEvent(ATB_HEALTH_MODE mode, const QString & errorNumber, const QString & errorDescription) :
QEvent(ATB_HEALTH_EVENT),
healthMode(mode),
errorNumber(errorNumber),
errorDescription(errorDescription)
{
}
QString ATBHealthEvent::getErrorNumber()
{
return this->errorNumber;
}
QString ATBHealthEvent::getErrorDescription()
{
return this->errorDescription;
}
ATB_HEALTH_MODE ATBHealthEvent::getMode()
{
return this->healthMode;
}

View File

@ -1,44 +0,0 @@
#ifndef ATBHEALTHEVENT_H
#define ATBHEALTHEVENT_H
#include <QEvent>
#include <QString>
enum class ATB_HEALTH_MODE : quint8;
const QEvent::Type ATB_HEALTH_EVENT = static_cast<QEvent::Type>(QEvent::User + 1);
class ATBHealthEvent : public QEvent
{
public:
ATBHealthEvent(ATB_HEALTH_MODE mode, const QString & errorNumber, const QString & errorDescription);
QString getErrorNumber();
QString getErrorDescription();
ATB_HEALTH_MODE getMode();
signals:
public slots:
private:
ATB_HEALTH_MODE healthMode;
QString errorNumber;
QString errorDescription;
};
enum class ATB_HEALTH_MODE : quint8 {
WARNING,
ERROR,
WARNING_CORRECTION,
ERROR_CORRECTION,
DEBUG,
STATE,
UNSPECIFIED
};
#endif // ATBHEALTHEVENT_H

View File

@ -1,69 +0,0 @@
/* Machine Event
*
* Used e.g. to send events to ISMAS
*
* Note: It's an Event, not a State!
* -> An Event may cause a transition to a different state, depending on the current state.
* -> Compare to edge/level trigger: Event is an "edge", State is a "level"
* => Do not mix both
*
*/
#include <QDateTime>
#include "ATBMachineEvent.h"
ATBMachineEvent::ATBMachineEvent(
const QString & id,
const QString & deviceName, // PTU/PRINTER/DC/...
EVENT_CLASS eventClass, // reason of event: Error/Warning/Alarm
const QString & name, // 'Event': "E001", "W003"
const int state,
const QString & parameter,
const QString & secondLevelInfo)
: QEvent(ATB_MACHINE_EVENT)
, eventId(id)
, deviceName(deviceName)
, machineEventClass(eventClass)
, eventName(name)
, eventState(state)
// timestamp including timezone offset
, timestampString(QDateTime::currentDateTime().toOffsetFromUtc(
QDateTime::currentDateTime().offsetFromUtc()).toString(Qt::ISODate)
)
, parameterString(parameter)
, secondLevelInfoString(secondLevelInfo)
{
}
QString ATBMachineEvent::getEventClassString(EVENT_CLASS eventClass)
{
switch (eventClass) {
case EVENT_CLASS::WARNING:
return "WARNING";
break;
case EVENT_CLASS::ERROR:
return "ERROR";
break;
case EVENT_CLASS::ALARM:
return "ALARM";
break;
case EVENT_CLASS::DEBUG:
return "DEBUG";
break;
case EVENT_CLASS::STATE:
return "STATE";
break;
case EVENT_CLASS::OPERATE:
return "OPERATE";
break;
case EVENT_CLASS::NOT_DEFINED:
return "NOT_DEFINED";
break;
}
return "NOT_DEFINED";
}

View File

@ -1,48 +0,0 @@
#ifndef ATBMACHINECONDITIONEVENT_H
#define ATBMACHINECONDITIONEVENT_H
#include <QEvent>
#include <QString>
enum class EVENT_CLASS : quint8;
const QEvent::Type ATB_MACHINE_EVENT = static_cast<QEvent::Type>(QEvent::User + 2);
class ATBMachineEvent : public QEvent
{
public:
explicit ATBMachineEvent(const QString & id,
const QString & deviceName, // PTU/PRINTER/DC/...
EVENT_CLASS eventClass, // reason of event: Error/Warning/Alarm
const QString & name, // 'Event': "E001", "W003"
const int state,
const QString & parameter,
const QString & secondLevelInfo
);
QString eventId;
QString deviceName;
EVENT_CLASS machineEventClass;
QString eventName;
int eventState;
QString timestampString;
QString parameterString;
QString secondLevelInfoString;
static QString getEventClassString(EVENT_CLASS eventClass);
};
enum class EVENT_CLASS : quint8 {
WARNING,
ERROR,
ALARM,
DEBUG,
STATE,
OPERATE,
NOT_DEFINED
};
#endif // ATBMACHINEEVENT_H

View File

@ -1,628 +0,0 @@
#include "DeviceControllerDiag.h"
#include <QCoreApplication>
#include <QMetaEnum>
#include <QUuid>
#include <QDebug>
#include <QProcess>
#include "support/JSON.h"
DeviceControllerDiag::DeviceControllerDiag(PersistentData *pData, QObject *parent)
: QObject(parent)
, coinProcessorType(nsDeviceControllerInterface::COIN_PROCESSOR::ESCROW)
, billAcceptor(nsDeviceControllerInterface::BILL_ACCEPTOR::NO)
, eventReceiver(nullptr)
, isRequestRunning(false)
, flagInterruptDiag(false)
, lastState(DeviceController::State::INITIAL_STATE)
, _isErrorState(false)
, pData(pData)
, E255counter(0)
{
diagRequestTimeoutTimer = new QTimer(this);
diagRequestTimeoutTimer->setInterval(1000*45);
diagRequestTimeoutTimer->setSingleShot(true);
connect(diagRequestTimeoutTimer, &QTimer::timeout, this, &DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout);
}
void DeviceControllerDiag::init(hwinf *hw, QObject* eventReceiver)
{
this->hw = hw;
this->eventReceiver = eventReceiver;
// make a system check on startup:
QTimer::singleShot(2000, this, &DeviceControllerDiag::diagRequest);
}
void DeviceControllerDiag::diagReInit()
{
this->machineEventSet.clear();
this->_isErrorState = false;
}
void DeviceControllerDiag::setTimeout(int timeout)
{
this->diagRequestTimeoutTimer->setInterval(1000 * timeout);
}
void DeviceControllerDiag::diagRequest()
{
qCritical() << "DeviceControllerDiag::diagRequest()";
if (this->isRequestRunning) {
qCritical() << "DeviceControllerDiag::diagRequest() is already running";
return;
}
this->isRequestRunning = true;
this->diagRequestTimeoutTimer->start();
this->private_startDiag();
// read dc-fw-version:
/* note: dc_getSWVersion() returns always 32 characters (QString)...
* if no version string could be read it will contain 32 null-characters:
* "\u0000\u0000..."
*/
QString dc_fw_version = hw->dc_getSWversion().remove(QChar('\0'));
qCritical() << "ATBDeviceControllerPlugin: DC firmware version: " << dc_fw_version;
this->pData->setDCFirmwareVersion(dc_fw_version);
this->pData->serializeToFile();
}
void DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()
{
qCritical() << "DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()";
this->flagInterruptDiag = true;
}
bool DeviceControllerDiag::isErrorState()
{
return this->_isErrorState;
}
bool DeviceControllerDiag::isOperatingState()
{
return !this->_isErrorState;
}
QSet<DeviceController::State> DeviceControllerDiag::getCurrentMachineState()
{
return this->machineEventSet;
}
void DeviceControllerDiag::private_startDiag()
{
// check for DiagRequestTimeoutTimerTimeout:
if (this->flagInterruptDiag) {
qCritical() << "DeviceControllerDiag::private_startDiag() interrupted!";
this->private_sendDiagEvent(DeviceController::State::E255);
this->isRequestRunning = false;
this->flagInterruptDiag = false;
if (this->E255counter > 5) {
this->restartCArun();
}
else {
this->E255counter++;
// try it again, until success:
QTimer::singleShot(400, this, &DeviceControllerDiag::diagRequest);
/**
* But please note:
* - diag does currently not stop suspend (start a background task)
* - diag is called again in ModeOOO wokeup()
*/
}
return;
}
bool result;
result = hw->sys_areDCdataValid();
if (result) {
qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is valid";
QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
}
else {
qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is +++not+++ valid";
// try it again
QTimer::singleShot(200, this, &DeviceControllerDiag::private_startDiag);
}
}
void DeviceControllerDiag::sys_superviseSystem()
{ // this function proofs if vending is possible depending of doors state
struct T_dynamicCondition dynMaCond = {};
struct T_moduleCondition modCond = {};
qCritical() << " sys_superviseSystem()";
// check for DiagRequestTimeoutTimerTimeout:
if (this->flagInterruptDiag) {
qCritical() << "DeviceControllerDiag::sys_superviseSystem() interrupted!";
this->private_sendDiagEvent(DeviceController::State::E255);
this->flagInterruptDiag = false;
this->isRequestRunning = false;
if (this->E255counter > 5) { this->restartCArun(); }
else { this->E255counter++; }
return;
}
if (!hw->sys_areDCdataValid())
{
// es gibt keinerlei gültige Daten vom DC
qCritical() << "DeviceControllerDiag::sys_superviseSystem() no valid data!";
this->private_sendDiagEvent(DeviceController::State::E254);
this->diagRequestTimeoutTimer->stop();
this->isRequestRunning = false;
if (this->E255counter > 5) { this->restartCArun(); }
else { this->E255counter++; }
return;
}
// jetzt sind die DC-Daten aktuell, also reinholen:
hw->sys_getDynMachineConditions(&dynMaCond);
hw->sys_getDeviceConditions(&modCond);
qCritical() << "DeviceControllerDiag::sys_superviseSystem() get condition data";
if (!modCond.allModulesChecked)
{
// noch keine Testergebnisse
if (dynMaCond.startupTestIsRunning) {
qCritical() << " startupTestIsRunning --> call again";
}
qCritical() << " allModulesChecked is false --> call again";
QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
return;
}
qCritical() << " --> call sub_componentAssessment()";
sub_componentAssessment();
}
void DeviceControllerDiag::sub_componentAssessment()
{
bool flag_sendOperate = true;
struct T_moduleCondition modCond = {};
hw->sys_getDeviceConditions(&modCond);
struct T_dynamicCondition dynMaCond = {};
hw->sys_getDynMachineConditions(&dynMaCond);
struct T_devices devPara = {};
hw->sys_restoreDeviceParameter(&devPara);
// store some interesting results:
// -> voltage:
uint32_t voltage = hw->dc_getVoltage();
emit newVoltage(voltage);
// check for alarm:
if (dynMaCond.onAlarm>0) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::A000);
}
// check for open doors
// all doors: 99: undefined 0:closed 1:open
if (dynMaCond.lowerDoor || dynMaCond.upperDoor) {
// Service or battery door is open
flag_sendOperate = false;
qCritical() << "DeviceControllerDiag::sys_superviseSystem() Service or battery door is open, goto INTRUSION MODE";
this->private_sendDiagEvent(DeviceController::State::E253);
}
if (dynMaCond.middleDoor) {
// vault door is open
flag_sendOperate = false;
qCritical() << "DeviceControllerDiag::sys_superviseSystem() vault door is open, goto INTRUSION MODE";
this->private_sendDiagEvent(DeviceController::State::E252);
}
// check for invalid states:
if (modCond.rtc>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E002);
}
if (modCond.printer==200 || modCond.printer==201) { // 200: not connected 201: printer-HW-error 202: no paper
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E020);
}
if (modCond.printer==202) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E018);
}
if (modCond.coinBlocker>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E025);
}
if (modCond.mdbBus>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E034);
}
if (modCond.intEe>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E011);
}
// 2023-07-26: workaround for 00281/Szeged --------------------------------------------------------------
// because we need certain errors and we do get for 'kindOfCoinChecker' -> 16 !
qCritical() << "-----------diag: kindOfCoinChecker = " << devPara.kindOfCoinChecker;
qCritical() << " modCond.coinSafe = " << modCond.coinSafe;
if (devPara.kindOfCoinChecker > 0) {
if (modCond.coinSafe==201) { // full
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E007);
}
if (modCond.coinSafe==200) { // 200: kasse fehlt 201: voll 100:fast voll 1:ok
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E009);
}
if (modCond.coinEscrow>=200) {
flag_sendOperate = false;
// coinEscrow>200 is considered a warning:
this->private_sendDiagEvent(DeviceController::State::W010);
}
}
// -----------------------------------------------------------------------------------------------
switch (devPara.kindOfCoinChecker) {
case 0:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::NONE;
break;
case 1:
case 2:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::ESCROW;
break;
case 3:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::CHANGER;
break;
}
if (devPara.kindOfCoinChecker==1 || devPara.kindOfCoinChecker==2) // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW)
{
if (modCond.coinEscrow>=200) {
flag_sendOperate = false;
// coinEscrow>200 is considered a warning:
this->private_sendDiagEvent(DeviceController::State::W010);
}
if (modCond.coinSafe==201) { // full
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E007);
}
if (modCond.coinSafe==200) { // 200: kasse fehlt 201: voll 100:fast voll 1:ok
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E009);
}
} else
if (devPara.kindOfCoinChecker==3)
{
if (modCond.changer>=200) {
// Fehler Münzver.
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E026);
}
if (modCond.coinSafe==201) { // full
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E007);
}
if (modCond.coinSafe == 200) { // 200: kasse fehlt 201: voll 100:fast voll 1:ok
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E009);
}
}
switch (devPara.BillAcceptor) {
case 0:
this->billAcceptor = nsDeviceControllerInterface::BILL_ACCEPTOR::NO;
break;
default:
this->billAcceptor = nsDeviceControllerInterface::BILL_ACCEPTOR::YES;
break;
}
/*
if ( modCond.billReader>=200 && devPara.BillAcceptor>0)
{
if (modCond.billReader == 200) // 200: kasse fehlt 201: voll 100:fast voll 1:ok
{
return TODO;
}
if (modCond.billReader == 201) // 200: kasse fehlt 201: voll 100:fast voll 1:ok
{
return TODO;
}
}
*/
if (dynMaCond.modeAbrech>0) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E011);
}
if (dynMaCond.nowCardTest>0) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E072);
}
if (dynMaCond.startupTestIsRunning>0) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E073);
}
if (modCond.voltage>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::E003);
}
if (modCond.temper>=200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::W004);
}
// check for warnings
if (modCond.printer>=100 && modCond.printer<200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::W001);
}
if (modCond.coinSafe>=100 && modCond.coinSafe<200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::W002);
}
if (modCond.voltage>=100 && modCond.voltage<200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::W003);
}
if (modCond.temper>=100 && modCond.temper<200) {
flag_sendOperate = false;
this->private_sendDiagEvent(DeviceController::State::W004);
}
if (flag_sendOperate) {
this->private_sendDiagEvent(DeviceController::State::O000);
}
// finish diag
this->diagRequestTimeoutTimer->stop();
this->isRequestRunning = false;
this->flagInterruptDiag = false;
}
/**
* @brief DeviceControllerDiag::private_sendDiagEvent
* @param result - result value from 'sub_componentAssessment()',
* - 0x00 everything is fine
* - 0xFF on timer interrupt
* - 0xFE no valid data from DeviceController
* - 0xFD Service or battery door is open
* - 0xFE vault door is open
*/
void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
{
qCritical() << "DeviceControllerDiag::private_sendDiagEvent() result: " << result;
if (this->eventReceiver == nullptr) {
qCritical() << "DeviceControllerDiag: no eventReceiver";
return;
}
if (machineEventSet.contains(result)) {
// do not send already sent events
qCritical() << " ... is in machineEventList";
return;
}
else {
machineEventSet.insert(result);
}
QString eventId = QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 8);
QString eventName = QMetaEnum::fromType<DeviceController::State>().valueToKey(result);;
EVENT_CLASS eventClass = EVENT_CLASS::STATE;
QString parameter;
switch (result) {
case DeviceController::State::INITIAL_STATE:
break;
case DeviceController::State::A000: // alarm / intrusion
eventClass = EVENT_CLASS::ALARM;
parameter = "alarm / intrusion";
this->_isErrorState = true;
break;
case DeviceController::State::E002: // real time clock error
eventClass = EVENT_CLASS::ERROR;
parameter = "real time clock error";
this->_isErrorState = true;
break;
case DeviceController::State::E003: // voltage error
eventClass = EVENT_CLASS::ERROR;
parameter = "voltage error";
this->_isErrorState = true;
break;
case DeviceController::State::E004: // temperature error
eventClass = EVENT_CLASS::ERROR;
parameter = "temperature error";
this->_isErrorState = true;
break;
case DeviceController::State::E007: // coin safe full
eventClass = EVENT_CLASS::ERROR;
parameter = "coin safe full";
this->_isErrorState = true;
break;
case DeviceController::State::E008: // bill acceptor full
eventClass = EVENT_CLASS::ERROR;
parameter = "bill acceptor full";
this->_isErrorState = true;
break;
case DeviceController::State::E009: // no cash box
eventClass = EVENT_CLASS::ERROR;
parameter = "no cash box";
this->_isErrorState = true;
break;
case DeviceController::State::E010: // coin escrow
eventClass = EVENT_CLASS::ERROR;
parameter = "coin escrow";
this->_isErrorState = true;
break;
case DeviceController::State::W010: // coin escrow
eventClass = EVENT_CLASS::WARNING;
parameter = "coin escrow";
break;
case DeviceController::State::E011: // mem error int.ee.
eventClass = EVENT_CLASS::ERROR;
parameter = "mem error int.ee.";
this->_isErrorState = true;
break;
case DeviceController::State::E018: // no paper
eventClass = EVENT_CLASS::ERROR;
parameter = "no paper";
this->_isErrorState = true;
break;
case DeviceController::State::E020: // printer error
eventClass = EVENT_CLASS::ERROR;
parameter = "printer error";
this->_isErrorState = true;
break;
case DeviceController::State::E025: // coin blocker
eventClass = EVENT_CLASS::ERROR;
parameter = "coin blocker";
this->_isErrorState = true;
break;
case DeviceController::State::E026: // error coin validator
eventClass = EVENT_CLASS::ERROR;
parameter = "error coin validator";
this->_isErrorState = true;
break;
case DeviceController::State::E034: // mdb error
eventClass = EVENT_CLASS::ERROR;
parameter = "mdb error";
this->_isErrorState = true;
break;
case DeviceController::State::E071: // cash box change is ongoing
eventClass = EVENT_CLASS::STATE;
parameter = "cash box change is ongoing";
break;
case DeviceController::State::E072: // card test running
eventClass = EVENT_CLASS::STATE;
parameter = "card test running";
break;
case DeviceController::State::E073: // startup-test is running
eventClass = EVENT_CLASS::STATE;
parameter = "startup-test is running";
break;
case DeviceController::State::E252: // cash box door open
eventClass = EVENT_CLASS::STATE;
parameter = "cash box door open";
break;
case DeviceController::State::E253: // service or battery door open
eventClass = EVENT_CLASS::STATE;
parameter = "service or battery door open";
break;
case DeviceController::State::E254: // no valid data from DeviceController
eventClass = EVENT_CLASS::STATE;
parameter = "no valid data from DeviceController";
break;
case DeviceController::State::E255: // no valid data from DeviceController
eventClass = EVENT_CLASS::ERROR;
parameter = "no valid data from DeviceController";
break;
case DeviceController::State::O000: // everything is fine
this->machineEventSet.clear();
this->_isErrorState = false;
eventClass = EVENT_CLASS::OPERATE;
parameter = "";
if (this->lastState == DeviceController::State::O000) {
qCritical() << " ... everything fine, no state change -> skip sending";
return;
}
else {
qCritical() << " ... everything fine";
}
break;
case DeviceController::State::W001: // paper low
eventClass = EVENT_CLASS::WARNING;
parameter = "paper low";
break;
case DeviceController::State::W002: // cashbox almost full
eventClass = EVENT_CLASS::WARNING;
parameter = "cashbox almost full";
break;
case DeviceController::State::W003: // voltage low
eventClass = EVENT_CLASS::WARNING;
parameter = "voltage low";
break;
case DeviceController::State::W004: // temperatur warning
eventClass = EVENT_CLASS::WARNING;
parameter = "temperatur warning";
break;
case DeviceController::State::W255: // restart carun
eventClass = EVENT_CLASS::WARNING;
parameter = "restart carun";
break;
}
this->lastState = result;
/**
* Variant: send 'parameter' as JSON:
*
JSON::setPrettySerialize(false);
JSON::JsonObject json = JSON::objectBuilder()
->set("description", parameter)
->create();
QString parameterJsonString = JSON::serialize(json);
*/
ATBMachineEvent *machineEvent = new ATBMachineEvent(
eventId,
"DC",
eventClass,
eventName,
1, // eventState
parameter,
"" // second level info
);
QCoreApplication::postEvent(eventReceiver, machineEvent);
}
/**
* reset / restart / reinit deviceController
*/
void DeviceControllerDiag::restartCArun()
{
this->E255counter = 0;
this->private_sendDiagEvent(DeviceController::State::W255);
QProcess::startDetached("/bin/systemctl", {"restart", "carun"});
}

View File

@ -1,140 +0,0 @@
#ifndef DEVICECONTROLLERDIAG_H
#define DEVICECONTROLLERDIAG_H
#include <QObject>
#include <QSet>
#include <QTimer>
#include <DeviceController/interfaces.h>
#include "DeviceControllerInterface.h"
#include "ATBMachineEvent.h"
#include "support/PersistentData.h"
namespace DeviceController {
Q_NAMESPACE
enum State {
O000,
A000,
E002,
E003,
E004,
E007,
E008,
E009,
E010,
W010, // Coin Escrow
E011,
E018,
E020,
E025,
E026,
E034,
E071,
E072,
E073,
E252,
E253,
E254,
E255,
W001,
W002,
W003,
W004,
W255,
INITIAL_STATE
};
Q_ENUM_NS(State)
}
class DeviceControllerDiag : public QObject
{
Q_OBJECT
public:
DeviceControllerDiag(PersistentData *pData, QObject *parent = nullptr);
void init(hwinf* hw, QObject* eventReceiver);
nsDeviceControllerInterface::COIN_PROCESSOR coinProcessorType;
nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor;
/**
* return true, if machineEventSet contains an error
*/
bool isErrorState();
bool isOperatingState();
QSet<DeviceController::State> getCurrentMachineState();
void setTimeout(int timeout);
public slots:
/**
* start diag request
*/
void diagRequest();
/**
* reset / re-init diag request.
* Called e.g. when doors are closed.
*/
void diagReInit();
/**
* reset / restart / reinit deviceController
*/
void restartCArun();
signals:
void diagResponse(ATBMachineEvent* machineEvent);
void newVoltage(uint32_t voltage);
private:
QObject *eventReceiver;
hwinf* hw;
bool isRequestRunning;
bool flagInterruptDiag;
QTimer *diagRequestTimeoutTimer;
void sub_componentAssessment(); // diag exit method
int lastVoltage;
DeviceController::State lastState;
QSet<DeviceController::State> machineEventSet;
bool _isErrorState;
PersistentData* pData;
int E255counter;
private slots:
void onDiagRequestTimeoutTimerTimeout();
void private_startDiag(); // diag entry method
void private_sendDiagEvent(DeviceController::State result);
void sys_superviseSystem();
};
#endif // DEVICECONTROLLERDIAG_H

View File

@ -1,273 +0,0 @@
#ifndef DEVICECONTROLLERINTERFACE_H
#define DEVICECONTROLLERINTERFACE_H
#include <QtPlugin>
#include <QSettings>
#include <QString>
#include <QJsonObject>
#include "ATBAPPplugin.h"
namespace nsDeviceControllerInterface {
enum class PLUGIN_STATE : quint8;
enum class RESULT_STATE : quint8;
enum class CASH_STATE : quint8;
enum class TICKET_VARIANT : quint8;
enum class COIN_PROCESSOR : quint8;
enum class BILL_ACCEPTOR : quint8;
enum class SERVICE_TEXT : quint16;
}
class DeviceControllerInterface : public QObject
, public ATBAPPplugin
{
Q_OBJECT
Q_INTERFACES(ATBAPPplugin)
public:
virtual ~DeviceControllerInterface() {}
/**
* @brief initDCPlugin
* @param eventReceiver - QObject to receive ATBMachineEvents or HealthEvents
* @param settings
* @return
*/
virtual nsDeviceControllerInterface::PLUGIN_STATE initDCPlugin(QObject *eventReceiver,
const QSettings & settings) = 0;
/**
* e.g. send location
*/
virtual void sendDeviceParameter(const QJsonObject & jsonObject) = 0;
// TASKS: Cash handling -------------------------------------------------------
/**
* enables coin input
* amount = "0": pay-up
* amount > "0": pay-down
*/
virtual void requestStartCashInput(const QString & amount) = 0;
/**
* called e.g. on Button "NEXT" in pay-up (direct coin input)
*/
virtual void requestStopCashInput() = 0;
/**
* called e.g. after printing
*/
virtual void cashCollect() = 0;
virtual void cashCollect(const QString & amount) = 0;
virtual void cashAbort() = 0;
// TASKS: Account -------------------------------------------------------------
virtual void requestAccount() = 0;
// TASKS: printing ------------------------------------------------------------
virtual void requestPrintTicket(const QHash<QString, QVariant> & printingData) = 0;
virtual void requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash<QString, QVariant> & printingData) = 0;
virtual void requestPrintReceipt(const QHash<QString, QVariant> & printingData) = 0;
virtual void requestPrintReceipt(const QString & printingString) = 0;
// read coin/cash processing variants
virtual nsDeviceControllerInterface::COIN_PROCESSOR coinProcessor() = 0;
virtual nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor() = 0;
// mandantory ATBAPP plugin methods:
virtual nsDeviceControllerInterface::PLUGIN_STATE getState() = 0;
virtual const QString & 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(nsDeviceControllerInterface::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(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & errorCode,
const QString & errorDescription);
void printReceiptFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & errorCode,
const QString & errorDescription);
void coinAttached();
/**
* emitted on e.g. a coin input
*/
void cashInputEvent(nsDeviceControllerInterface::RESULT_STATE resultState,
nsDeviceControllerInterface::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(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & newCashValue,
const QString & coinValue,
const QString & noteValue,
const QString & changeValue,
const QString & errorCode,
const QString & errorDescription);
/**
* emitted if cashPayment has been finished, e.g. in result to task cashCollect():
* if coins in changer must be given back to user.
*/
void cashPaymentChanging(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & changeValue, // amount changed by changer/escrow
const QString & errorCode,
const QString & errorDescription);
/**
* emitted if cashPayment has been finished, e.g. in result to task cashCollect():
* -> ticket should be printed sucessfully
* -> coins in excrow or changer are given back to user
* Provides data for logging, especially changed value
*/
void cashPaymentFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & newCashValue, // total inserted amount
const QString & coinValue, // inserted amount, paid with coins
const QString & noteValue, // inserted amount, paid with notes
const QString & changeValue, // amount changed by changer/escrow
const QString & errorCode,
const QString & errorDescription);
/**
* emitted e.g. if service door is opened
*/
void requestModeSERVICE();
/**
* emitted e.g. if vault door is opened
*/
void requestModeACCOUNT();
/**
* 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);
/**
* show text messages in service mode
*/
void showServiceText(nsDeviceControllerInterface::SERVICE_TEXT serviceText, const QString & text);
/**
* 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(DeviceControllerInterface,
"eu.atb.ptu.plugin.DeviceControllerInterface/1.2.0")
namespace nsDeviceControllerInterface {
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
FINE_PAYMENT, // e.g. Klaipeda
FOOD_STAMP,
FREE_TICKET
};
enum class COIN_PROCESSOR : quint8 {
CHANGER,
ESCROW,
NONE
};
enum class BILL_ACCEPTOR : quint8 {
YES,
NO
};
enum class SERVICE_TEXT : quint16 {
SERVICE_DOOR_OPENED,
VAULT_DOOR_OPENED,
COIN_BOX_REMOVED,
COIN_BOX_INSERTED
/* t.b.d. */
};
}
#endif // DEVICECONTROLLERINTERFACE_H

View File

@ -1,18 +0,0 @@
#include "Utils.h"
Utils::Utils(QObject *parent) : QObject(parent)
{
}
int Utils::compare(const void* a, const void* b)
{
uint16_t int_a = * ( (uint16_t*) a );
uint16_t int_b = * ( (uint16_t*) b );
if ( int_a == int_b ) return 0;
else if ( int_a < int_b ) return -1;
else return 1;
}

View File

@ -1,23 +0,0 @@
#ifndef UTILS_H
#define UTILS_H
#include <QObject>
class Utils : public QObject
{
Q_OBJECT
public:
static int compare(const void* a, const void* b);
private:
explicit Utils(QObject *parent = nullptr);
signals:
};
#endif // UTILS_H

View File

@ -1,74 +0,0 @@
#include "CashUtils.h"
#include <QDebug>
#define MAX_COINS 64
#define MAX_NOTES 16
/*****************************************************************************
* Get current inserted coins
*
* getAllInsertedCoins(uint16_t *types, uint16_t *values)
* all inserted coins of this past transaction are stored, max 64
*/
uint32_t CashUtils::getAmountOfInsertedCoins(hwinf* hw)
{
uint32_t result = 0;
uint16_t types[MAX_COINS];
uint16_t values[MAX_COINS];
hw->getAllInsertedCoins(types, values);
for (int i = 0; i < MAX_COINS; i++) {
result += values[i];
}
return result;
}
/*****************************************************************************
* Get current inserted notes
*
* virtual uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const =0;
* returns number of collected bank notes since start-command (current transaction)
* latestBill: last accepted bank note, value in cent
* currentNotes an array with up to 16 (further) notes collected
*
*/
uint32_t CashUtils::getAmountOfInsertedNotes(hwinf* hw)
{
uint32_t result = 0;
uint8_t numberOfInsertedNotes;
uint16_t beforeArray = 0;
uint16_t currentNotes[4];
uint16_t afterArray = 0;
numberOfInsertedNotes = hw->bna_getCurrentNotes(0, currentNotes);
if ( (beforeArray != 0) || (afterArray != 0) ) {
qCritical() << "CashUtils::getAmountOfInsertedNotes() ERROR: Array";
}
if (numberOfInsertedNotes == 99) {
// Error
qCritical() << "CashUtils::getAmountOfInsertedNotes() ERROR: ";
for (int i = 0; i < 4; i++) {
qCritical() << " currentNotes[" << i << "] = " << currentNotes[i];
}
}
else {
// no error
result = currentNotes[3];
result = ( result << 16 ) | currentNotes[2];
}
// DEBUG
qCritical() << "--------------------------------------------------";
qCritical() << "CashUtils::getAmountOfInsertedNotes()";
qCritical() << " numberOfInsertedNotes = " << numberOfInsertedNotes;
qCritical() << " result = " << result;
qCritical() << "--------------------------------------------------";
return result;
}

View File

@ -1,14 +0,0 @@
#ifndef CASHUTILS_H
#define CASHUTILS_H
#include <QObject>
#include <DeviceController/interfaces.h>
namespace CashUtils {
uint32_t getAmountOfInsertedCoins(hwinf* hw);
uint32_t getAmountOfInsertedNotes(hwinf* hw);
}
#endif // CASHUTILS_H

View File

@ -1,14 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="eu.atb.ptu.systemcontrol">
<signal name="wokeUpFrom">
<arg name="source" type="y" direction="out"/>
</signal>
<method name="startBackgroundTask">
<arg name="id" type="s" direction="in"/>
</method>
<method name="finishedBackgroundTask">
<arg name="id" type="s" direction="in"/>
</method>
</interface>
</node>

View File

@ -1,26 +0,0 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -p DBusControllerInterface -c DBusControllerInterface DBusController.xml
*
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "DBusControllerInterface.h"
/*
* Implementation of interface class DBusControllerInterface
*/
DBusControllerInterface::DBusControllerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
{
}
DBusControllerInterface::~DBusControllerInterface()
{
}

View File

@ -1,64 +0,0 @@
/*
* This file was generated by qdbusxml2cpp version 0.7
* Command line was: qdbusxml2cpp -p DBusControllerInterface -c DBusControllerInterface DBusController.xml
*
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef DBUSCONTROLLERINTERFACE_H
#define DBUSCONTROLLERINTERFACE_H
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface eu.atb.ptu.systemcontrol
*/
class DBusControllerInterface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "eu.atb.ptu.systemcontrol"; }
public:
DBusControllerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~DBusControllerInterface();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> finishedBackgroundTask(const QString &id)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(id);
return asyncCallWithArgumentList(QLatin1String("finishedBackgroundTask"), argumentList);
}
inline QDBusPendingReply<> startBackgroundTask(const QString &id)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(id);
return asyncCallWithArgumentList(QLatin1String("startBackgroundTask"), argumentList);
}
Q_SIGNALS: // SIGNALS
void wokeUpFrom(uchar source);
};
namespace eu {
namespace atb {
namespace ptu {
typedef ::DBusControllerInterface systemcontrol;
}
}
}
#endif

View File

@ -1,735 +0,0 @@
#include <QDateTime>
#include <QStringList>
#include "JSON.h"
namespace JSON {
static QString dateFormat, dateTimeFormat;
static bool prettySerialize = false;
static QString sanitizeString(QString str);
static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep);
static QVariant parseValue(const QString &json, int &index, bool &success);
static QVariant parseObject(const QString &json, int &index, bool &success);
static QVariant parseArray(const QString &json, int &index, bool &success);
static QVariant parseString(const QString &json, int &index, bool &success);
static QVariant parseNumber(const QString &json, int &index);
static int lastIndexOfNumber(const QString &json, int index);
static void eatWhitespace(const QString &json, int &index);
static int lookAhead(const QString &json, int index);
static int nextToken(const QString &json, int &index);
template<typename T>
QByteArray serializeMap(const T &map, bool &success, int _level = 0) {
QByteArray newline;
QByteArray tabs;
QByteArray tabsFields;
if (prettySerialize && !map.isEmpty()) {
newline = "\n";
for (int l=1; l<_level; l++) {
tabs += " ";
}
tabsFields = tabs + " ";
}
QByteArray str = "{" + newline;
QList<QByteArray> pairs;
for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
bool otherSuccess = true;
QByteArray serializedValue = serialize(it.value(), otherSuccess, _level);
if (serializedValue.isNull()) {
success = false;
break;
}
pairs << tabsFields + sanitizeString(it.key()).toUtf8() + ":" + (prettySerialize ? " " : "") + serializedValue;
}
str += join(pairs, "," + newline) + newline;
str += tabs + "}";
return str;
}
void insert(QVariant &v, const QString &key, const QVariant &value);
void append(QVariant &v, const QVariant &value);
template<typename T>
void cloneMap(QVariant &json, const T &map) {
for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
insert(json, it.key(), (*it));
}
}
template<typename T>
void cloneList(QVariant &json, const T &list) {
for (typename T::const_iterator it = list.begin(), itend = list.end(); it != itend; ++it) {
append(json, (*it));
}
}
/**
* parse
*/
QVariant parse(const QString &json) {
bool success = true;
return parse(json, success);
}
/**
* parse
*/
QVariant parse(const QString &json, bool &success) {
success = true;
// Return an empty QVariant if the JSON data is either null or empty
if (!json.isNull() || !json.isEmpty()) {
QString data = json;
// We'll start from index 0
int index = 0;
// Parse the first value
QVariant value = parseValue(data, index, success);
// Return the parsed value
return value;
} else {
// Return the empty QVariant
return QVariant();
}
}
/**
* clone
*/
QVariant clone(const QVariant &data) {
QVariant v;
if (data.type() == QVariant::Map) {
cloneMap(v, data.toMap());
} else if (data.type() == QVariant::Hash) {
cloneMap(v, data.toHash());
} else if (data.type() == QVariant::List) {
cloneList(v, data.toList());
} else if (data.type() == QVariant::StringList) {
cloneList(v, data.toStringList());
} else {
v = QVariant(data);
}
return v;
}
/**
* insert value (map case)
*/
void insert(QVariant &v, const QString &key, const QVariant &value) {
if (!v.canConvert<QVariantMap>()) v = QVariantMap();
QVariantMap *p = (QVariantMap *)v.data();
p->insert(key, clone(value));
}
/**
* append value (list case)
*/
void append(QVariant &v, const QVariant &value) {
if (!v.canConvert<QVariantList>()) v = QVariantList();
QVariantList *p = (QVariantList *)v.data();
p->append(value);
}
QByteArray serialize(const QVariant &data) {
bool success = true;
return serialize(data, success);
}
QByteArray serialize(const QVariant &data, bool &success, int _level /*= 0*/) {
QByteArray newline;
QByteArray tabs;
QByteArray tabsFields;
if (prettySerialize) {
newline = "\n";
for (int l=0; l<_level; l++) {
tabs += " ";
}
tabsFields = tabs + " ";
}
QByteArray str;
success = true;
if (!data.isValid()) { // invalid or null?
str = "null";
} else if ((data.type() == QVariant::List) ||
(data.type() == QVariant::StringList)) { // variant is a list?
QList<QByteArray> values;
const QVariantList list = data.toList();
Q_FOREACH(const QVariant& v, list) {
bool otherSuccess = true;
QByteArray serializedValue = serialize(v, otherSuccess, _level+1);
if (serializedValue.isNull()) {
success = false;
break;
}
values << tabsFields + serializedValue;
}
if (!values.isEmpty()) {
str = "[" + newline + join( values, "," + newline ) + newline + tabs + "]";
} else {
str = "[]";
}
} else if (data.type() == QVariant::Hash) { // variant is a hash?
str = serializeMap<>(data.toHash(), success, _level+1);
} else if (data.type() == QVariant::Map) { // variant is a map?
str = serializeMap<>(data.toMap(), success, _level+1);
} else if ((data.type() == QVariant::String) ||
(data.type() == QVariant::ByteArray)) {// a string or a byte array?
str = sanitizeString(data.toString()).toUtf8();
} else if (data.type() == QVariant::Double) { // double?
double value = data.toDouble(&success);
if (success) {
str = QByteArray::number(value, 'g');
if (!str.contains(".") && ! str.contains("e")) {
str += ".0";
}
}
} else if (data.type() == QVariant::Bool) { // boolean value?
str = data.toBool() ? "true" : "false";
} else if (data.type() == QVariant::ULongLong) { // large unsigned number?
str = QByteArray::number(data.value<qulonglong>());
} else if (data.canConvert<qlonglong>()) { // any signed number?
str = QByteArray::number(data.value<qlonglong>());
} else if (data.canConvert<long>()) { //TODO: this code is never executed because all smaller types can be converted to qlonglong
str = QString::number(data.value<long>()).toUtf8();
} else if (data.type() == QVariant::DateTime) { // datetime value?
str = sanitizeString(dateTimeFormat.isEmpty()
? data.toDateTime().toString()
: data.toDateTime().toString(dateTimeFormat)).toUtf8();
} else if (data.type() == QVariant::Date) { // date value?
str = sanitizeString(dateTimeFormat.isEmpty()
? data.toDate().toString()
: data.toDate().toString(dateFormat)).toUtf8();
} else if (data.canConvert<QString>()) { // can value be converted to string?
// this will catch QUrl, ... (all other types which can be converted to string)
str = sanitizeString(data.toString()).toUtf8();
} else {
success = false;
}
if (success) {
return str;
}
return QByteArray();
}
QString serializeStr(const QVariant &data) {
return QString::fromUtf8(serialize(data));
}
QString serializeStr(const QVariant &data, bool &success) {
return QString::fromUtf8(serialize(data, success));
}
/**
* \enum JsonToken
*/
enum JsonToken {
JsonTokenNone = 0,
JsonTokenCurlyOpen = 1,
JsonTokenCurlyClose = 2,
JsonTokenSquaredOpen = 3,
JsonTokenSquaredClose = 4,
JsonTokenColon = 5,
JsonTokenComma = 6,
JsonTokenString = 7,
JsonTokenNumber = 8,
JsonTokenTrue = 9,
JsonTokenFalse = 10,
JsonTokenNull = 11
};
static QString sanitizeString(QString str) {
str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
str.replace(QLatin1String("\""), QLatin1String("\\\""));
str.replace(QLatin1String("\b"), QLatin1String("\\b"));
str.replace(QLatin1String("\f"), QLatin1String("\\f"));
str.replace(QLatin1String("\n"), QLatin1String("\\n"));
str.replace(QLatin1String("\r"), QLatin1String("\\r"));
str.replace(QLatin1String("\t"), QLatin1String("\\t"));
return QString(QLatin1String("\"%1\"")).arg(str);
}
static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) {
QByteArray res;
Q_FOREACH(const QByteArray &i, list) {
if (!res.isEmpty()) {
res += sep;
}
res += i;
}
return res;
}
/**
* parseValue
*/
static QVariant parseValue(const QString &json, int &index, bool &success) {
// Determine what kind of data we should parse by
// checking out the upcoming token
switch(lookAhead(json, index)) {
case JsonTokenString:
return parseString(json, index, success);
case JsonTokenNumber:
return parseNumber(json, index);
case JsonTokenCurlyOpen:
return parseObject(json, index, success);
case JsonTokenSquaredOpen:
return parseArray(json, index, success);
case JsonTokenTrue:
nextToken(json, index);
return QVariant(true);
case JsonTokenFalse:
nextToken(json, index);
return QVariant(false);
case JsonTokenNull:
nextToken(json, index);
return QVariant();
case JsonTokenNone:
break;
}
// If there were no tokens, flag the failure and return an empty QVariant
success = false;
return QVariant();
}
/**
* parseObject
*/
static QVariant parseObject(const QString &json, int &index, bool &success) {
QVariantMap map;
int token;
// Get rid of the whitespace and increment index
nextToken(json, index);
// Loop through all of the key/value pairs of the object
bool done = false;
while (!done) {
// Get the upcoming token
token = lookAhead(json, index);
if (token == JsonTokenNone) {
success = false;
return QVariantMap();
} else if (token == JsonTokenComma) {
nextToken(json, index);
} else if (token == JsonTokenCurlyClose) {
nextToken(json, index);
return map;
} else {
// Parse the key/value pair's name
QString name = parseString(json, index, success).toString();
if (!success) {
return QVariantMap();
}
// Get the next token
token = nextToken(json, index);
// If the next token is not a colon, flag the failure
// return an empty QVariant
if (token != JsonTokenColon) {
success = false;
return QVariant(QVariantMap());
}
// Parse the key/value pair's value
QVariant value = parseValue(json, index, success);
if (!success) {
return QVariantMap();
}
// Assign the value to the key in the map
map[name] = value;
}
}
// Return the map successfully
return QVariant(map);
}
/**
* parseArray
*/
static QVariant parseArray(const QString &json, int &index, bool &success) {
QVariantList list;
nextToken(json, index);
bool done = false;
while(!done) {
int token = lookAhead(json, index);
if (token == JsonTokenNone) {
success = false;
return QVariantList();
} else if (token == JsonTokenComma) {
nextToken(json, index);
} else if (token == JsonTokenSquaredClose) {
nextToken(json, index);
break;
} else {
QVariant value = parseValue(json, index, success);
if (!success) {
return QVariantList();
}
list.push_back(value);
}
}
return QVariant(list);
}
/**
* parseString
*/
static QVariant parseString(const QString &json, int &index, bool &success) {
QString s;
QChar c;
eatWhitespace(json, index);
c = json[index++];
bool complete = false;
while(!complete) {
if (index == json.size()) {
break;
}
c = json[index++];
if (c == '\"') {
complete = true;
break;
} else if (c == '\\') {
if (index == json.size()) {
break;
}
c = json[index++];
if (c == '\"') {
s.append('\"');
} else if (c == '\\') {
s.append('\\');
} else if (c == '/') {
s.append('/');
} else if (c == 'b') {
s.append('\b');
} else if (c == 'f') {
s.append('\f');
} else if (c == 'n') {
s.append('\n');
} else if (c == 'r') {
s.append('\r');
} else if (c == 't') {
s.append('\t');
} else if (c == 'u') {
int remainingLength = json.size() - index;
if (remainingLength >= 4) {
QString unicodeStr = json.mid(index, 4);
int symbol = unicodeStr.toInt(0, 16);
s.append(QChar(symbol));
index += 4;
} else {
break;
}
}
} else {
s.append(c);
}
}
if (!complete) {
success = false;
return QVariant();
}
return QVariant(s);
}
/**
* parseNumber
*/
static QVariant parseNumber(const QString &json, int &index) {
eatWhitespace(json, index);
int lastIndex = lastIndexOfNumber(json, index);
int charLength = (lastIndex - index) + 1;
QString numberStr;
numberStr = json.mid(index, charLength);
index = lastIndex + 1;
bool ok;
if (numberStr.contains('.')) {
return QVariant(numberStr.toDouble(NULL));
} else if (numberStr.startsWith('-')) {
int i = numberStr.toInt(&ok);
if (!ok) {
qlonglong ll = numberStr.toLongLong(&ok);
return ok ? ll : QVariant(numberStr);
}
return i;
} else {
uint u = numberStr.toUInt(&ok);
if (!ok) {
qulonglong ull = numberStr.toULongLong(&ok);
return ok ? ull : QVariant(numberStr);
}
return u;
}
}
/**
* lastIndexOfNumber
*/
static int lastIndexOfNumber(const QString &json, int index) {
int lastIndex;
for(lastIndex = index; lastIndex < json.size(); lastIndex++) {
if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) {
break;
}
}
return lastIndex -1;
}
/**
* eatWhitespace
*/
static void eatWhitespace(const QString &json, int &index) {
for(; index < json.size(); index++) {
if (QString(" \t\n\r").indexOf(json[index]) == -1) {
break;
}
}
}
/**
* lookAhead
*/
static int lookAhead(const QString &json, int index) {
int saveIndex = index;
return nextToken(json, saveIndex);
}
/**
* nextToken
*/
static int nextToken(const QString &json, int &index) {
eatWhitespace(json, index);
if (index == json.size()) {
return JsonTokenNone;
}
QChar c = json[index];
index++;
switch(c.toLatin1()) {
case '{': return JsonTokenCurlyOpen;
case '}': return JsonTokenCurlyClose;
case '[': return JsonTokenSquaredOpen;
case ']': return JsonTokenSquaredClose;
case ',': return JsonTokenComma;
case '"': return JsonTokenString;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '-': return JsonTokenNumber;
case ':': return JsonTokenColon;
}
index--; // ^ WTF?
int remainingLength = json.size() - index;
// True
if (remainingLength >= 4) {
if (json[index] == 't' && json[index + 1] == 'r' &&
json[index + 2] == 'u' && json[index + 3] == 'e') {
index += 4;
return JsonTokenTrue;
}
}
// False
if (remainingLength >= 5) {
if (json[index] == 'f' && json[index + 1] == 'a' &&
json[index + 2] == 'l' && json[index + 3] == 's' &&
json[index + 4] == 'e') {
index += 5;
return JsonTokenFalse;
}
}
// Null
if (remainingLength >= 4) {
if (json[index] == 'n' && json[index + 1] == 'u' &&
json[index + 2] == 'l' && json[index + 3] == 'l') {
index += 4;
return JsonTokenNull;
}
}
return JsonTokenNone;
}
void setDateTimeFormat(const QString &format) {
dateTimeFormat = format;
}
void setDateFormat(const QString &format) {
dateFormat = format;
}
QString getDateTimeFormat() {
return dateTimeFormat;
}
QString getDateFormat() {
return dateFormat;
}
void setPrettySerialize(bool enabled) {
prettySerialize = enabled;
}
bool isPrettySerialize() {
return prettySerialize;
}
QQueue<BuilderJsonObject *> BuilderJsonObject::created_list;
BuilderJsonObject::BuilderJsonObject() {
// clean objects previous "created"
while (!BuilderJsonObject::created_list.isEmpty()) {
delete BuilderJsonObject::created_list.dequeue();
}
}
BuilderJsonObject::BuilderJsonObject(JsonObject &json) {
BuilderJsonObject();
obj = json;
}
BuilderJsonObject *BuilderJsonObject::set(const QString &key, const QVariant &value) {
obj[key] = value;
return this;
}
BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonObject *builder) {
return set(key, builder->create());
}
BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonArray *builder) {
return set(key, builder->create());
}
JsonObject BuilderJsonObject::create() {
BuilderJsonObject::created_list.enqueue(this);
return obj;
}
QQueue<BuilderJsonArray *> BuilderJsonArray::created_list;
BuilderJsonArray::BuilderJsonArray() {
// clean objects previous "created"
while (!BuilderJsonArray::created_list.isEmpty()) {
delete BuilderJsonArray::created_list.dequeue();
}
}
BuilderJsonArray::BuilderJsonArray(JsonArray &json) {
BuilderJsonArray();
array = json;
}
BuilderJsonArray *BuilderJsonArray::add(const QVariant &element) {
array.append(element);
return this;
}
BuilderJsonArray *BuilderJsonArray::add(BuilderJsonObject *builder) {
return add(builder->create());
}
BuilderJsonArray *BuilderJsonArray::add(BuilderJsonArray *builder) {
return add(builder->create());
}
JsonArray BuilderJsonArray::create() {
BuilderJsonArray::created_list.enqueue(this);
return array;
}
BuilderJsonObject *objectBuilder() {
return new BuilderJsonObject();
}
BuilderJsonObject *objectBuilder(JsonObject &json) {
return new BuilderJsonObject(json);
}
BuilderJsonArray *arrayBuilder() {
return new BuilderJsonArray();
}
BuilderJsonArray *arrayBuilder(JsonArray &json) {
return new BuilderJsonArray(json);
}
} //end namespace

View File

@ -1,250 +0,0 @@
#ifndef JSON_H
#define JSON_H
#include <QVariant>
#include <QString>
#include <QQueue>
/**********************************************
* based on: https://github.com/qt-json/qt-json
*/
/**
* \namespace JSON
* \brief A JSON data parser
*
* Json parses a JSON data into a QVariant hierarchy.
*/
namespace JSON {
typedef QVariantMap JsonObject;
typedef QVariantList JsonArray;
/**
* Clone a JSON object (makes a deep copy)
*
* \param data The JSON object
*/
QVariant clone(const QVariant &data);
/**
* Insert value to JSON object (QVariantMap)
*
* \param v The JSON object
* \param key The key
* \param value The value
*/
void insert(QVariant &v, const QString &key, const QVariant &value);
/**
* Append value to JSON array (QVariantList)
*
* \param v The JSON array
* \param value The value
*/
void append(QVariant &v, const QVariant &value);
/**
* Parse a JSON string
*
* \param json The JSON data
*/
QVariant parse(const QString &json);
/**
* Parse a JSON string
*
* \param json The JSON data
* \param success The success of the parsing
*/
QVariant parse(const QString &json, bool &success);
/**
* This method generates a textual JSON representation
*
* \param data The JSON data generated by the parser.
*
* \return QByteArray Textual JSON representation in UTF-8
*/
QByteArray serialize(const QVariant &data);
/**
* This method generates a textual JSON representation
*
* \param data The JSON data generated by the parser.
* \param success The success of the serialization
*
* \return QByteArray Textual JSON representation in UTF-8
*/
QByteArray serialize(const QVariant &data, bool &success, int _level = 0);
/**
* This method generates a textual JSON representation
*
* \param data The JSON data generated by the parser.
*
* \return QString Textual JSON representation
*/
QString serializeStr(const QVariant &data);
/**
* This method generates a textual JSON representation
*
* \param data The JSON data generated by the parser.
* \param success The success of the serialization
*
* \return QString Textual JSON representation
*/
QString serializeStr(const QVariant &data, bool &success, int _level = 0);
/**
* This method sets date(time) format to be used for QDateTime::toString
* If QString is empty, Qt::TextDate is used.
*
* \param format The JSON data generated by the parser.
*/
void setDateTimeFormat(const QString& format);
void setDateFormat(const QString& format);
/**
* This method gets date(time) format to be used for QDateTime::toString
* If QString is empty, Qt::TextDate is used.
*/
QString getDateTimeFormat();
QString getDateFormat();
/**
* @brief setPrettySerialize enable/disabled pretty-print when serialize() a json
* @param enabled
*/
void setPrettySerialize(bool enabled);
/**
* @brief isPrettySerialize check if is enabled pretty-print when serialize() a json
* @return
*/
bool isPrettySerialize();
/**
* QVariant based Json object
*/
class Object : public QVariant {
template<typename T>
Object& insertKey(Object* ptr, const QString& key) {
T* p = (T*)ptr->data();
if (!p->contains(key)) p->insert(key, QVariant());
return *reinterpret_cast<Object*>(&p->operator[](key));
}
template<typename T>
void removeKey(Object *ptr, const QString& key) {
T* p = (T*)ptr->data();
p->remove(key);
}
public:
Object() : QVariant() {}
Object(const Object& ref) : QVariant(ref) {}
Object& operator=(const QVariant& rhs) {
/** It maybe more robust when running under Qt versions below 4.7 */
QObject * obj = qvariant_cast<QObject *>(rhs);
// setValue(rhs);
setValue(obj);
return *this;
}
Object& operator[](const QString& key) {
if (type() == QVariant::Map)
return insertKey<QVariantMap>(this, key);
else if (type() == QVariant::Hash)
return insertKey<QVariantHash>(this, key);
setValue(QVariantMap());
return insertKey<QVariantMap>(this, key);
}
const Object& operator[](const QString& key) const {
return const_cast<Object*>(this)->operator[](key);
}
void remove(const QString& key) {
if (type() == QVariant::Map)
removeKey<QVariantMap>(this, key);
else if (type() == QVariant::Hash)
removeKey<QVariantHash>(this, key);
}
};
class BuilderJsonArray;
/**
* @brief The BuilderJsonObject class
*/
class BuilderJsonObject {
public:
BuilderJsonObject();
BuilderJsonObject(JsonObject &json);
BuilderJsonObject *set(const QString &key, const QVariant &value);
BuilderJsonObject *set(const QString &key, BuilderJsonObject *builder);
BuilderJsonObject *set(const QString &key, BuilderJsonArray *builder);
JsonObject create();
private:
static QQueue<BuilderJsonObject *> created_list;
JsonObject obj;
};
/**
* @brief The BuilderJsonArray class
*/
class BuilderJsonArray {
public:
BuilderJsonArray();
BuilderJsonArray(JsonArray &json);
BuilderJsonArray *add(const QVariant &element);
BuilderJsonArray *add(BuilderJsonObject *builder);
BuilderJsonArray *add(BuilderJsonArray *builder);
JsonArray create();
private:
static QQueue<BuilderJsonArray *> created_list;
JsonArray array;
};
/**
* @brief Create a BuilderJsonObject
* @return
*/
BuilderJsonObject *objectBuilder();
/**
* @brief Create a BuilderJsonObject starting from copy of another json
* @return
*/
BuilderJsonObject *objectBuilder(JsonObject &json);
/**
* @brief Create a BuilderJsonArray
* @return
*/
BuilderJsonArray *arrayBuilder();
/**
* @brief Create a BuilderJsonArray starting from copy of another json
* @return
*/
BuilderJsonArray *arrayBuilder(JsonArray &json);
}
#endif // JSON_H

View File

@ -1,109 +0,0 @@
#include "PTUSystem.h"
#include <QDebug>
#include <QDir>
#include <QFileInfo>
PTUSystem::PTUSystem(QObject *parent) : QObject(parent)
{
}
quint16 PTUSystem::readCustomerNumber()
{
QString resultFilename;
QStringList fileNameList;
fileNameList << "/mnt/system_data/cust_nr"
<< "/etc/cust_nr";
for (const auto& filename : fileNameList) {
if (QFileInfo(filename).isReadable()) {
resultFilename = filename;
break;
}
}
QString resultString = PTUSystem::readConfigString(resultFilename);
return static_cast<quint16>(resultString.toInt());
}
quint16 PTUSystem::readMachineNumber()
{
QString resultFilename;
QStringList fileNameList;
fileNameList << "/mnt/system_data/machine_nr"
<< "/etc/machine_nr";
for (const auto& filename : fileNameList) {
if (QFileInfo(filename).isReadable()) {
resultFilename = filename;
break;
}
}
QString resultString = PTUSystem::readConfigString(resultFilename);
return static_cast<quint16>(resultString.toInt());
}
quint16 PTUSystem::readZoneNumber()
{
QString resultFilename;
QStringList fileNameList;
fileNameList << "/mnt/system_data/zone_nr"
<< "/etc/zone_nr";
for (const auto& filename : fileNameList) {
if (QFileInfo(filename).isReadable()) {
resultFilename = filename;
break;
}
}
QString resultString = PTUSystem::readConfigString(resultFilename);
return static_cast<quint16>(resultString.toInt());
}
quint16 PTUSystem::readGroupNumber()
{
QString resultFilename;
QStringList fileNameList;
fileNameList << "/mnt/system_data/group_nr"
<< "/etc/group_nr";
for (const auto& filename : fileNameList) {
if (QFileInfo(filename).isReadable()) {
resultFilename = filename;
break;
}
}
QString resultString = PTUSystem::readConfigString(resultFilename);
return static_cast<quint16>(resultString.toInt());
}
QString PTUSystem::readConfigString(const QString & filename)
{
QFileInfo fileinfo(filename);
if (! fileinfo.isReadable() ) {
qDebug() << "PTUSystem::readConfigString(): \"" << filename << "\" is not readable";
return "";
}
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "PTUSystem::readConfigString() cannot open file: " << filename;
return "";
}
QTextStream in(&file);
QString stringValue = in.readLine(100);
qDebug() << "PTUSystem::readConfigString() stringValue = " << stringValue;
file.close();
return stringValue;
}

View File

@ -1,24 +0,0 @@
#ifndef PTUSYSTEM_H
#define PTUSYSTEM_H
#include <QObject>
class PTUSystem : public QObject
{
Q_OBJECT
public:
explicit PTUSystem(QObject *parent = nullptr);
static quint16 readCustomerNumber();
static quint16 readMachineNumber();
static quint16 readZoneNumber();
static quint16 readGroupNumber();
private:
static QString readConfigString(const QString & filename);
signals:
};
#endif // PTUSYSTEM_H

View File

@ -1,145 +0,0 @@
#include "PersistentData.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QDateTime>
#include <QDataStream>
#include <QDebug>
PersistentData::PersistentData(const QString &datafileName, QObject *parent)
: QObject(parent)
, isChangedFlag(false)
{
// load persistant data, if available
this->filename = datafileName;
QFileInfo dataFileInfo(this->filename);
QString dataFilePath = dataFileInfo.path();
QDir dir;
if ( ! dir.exists(dataFilePath)) {
qCritical() << "Persistent data file does not exist!";
qCritical() << " --> create new: " << this->filename;
dir.mkpath(dataFilePath);
}
this->read();
}
void PersistentData::serializeToFile()
{
if (this->isChangedFlag) {
qCritical() << "PersistentData::isChanged -> save";
this->save();
}
}
void PersistentData::save()
{
QFile fileOut(this->filename);
if (fileOut.open(QIODevice::WriteOnly))
{
QDataStream out(&fileOut);
out.setVersion(QDataStream::Qt_4_6);
out << this->hash;
fileOut.flush();
fileOut.close();
this->isChangedFlag = false;
}
}
void PersistentData::read()
{
QFile fileIn(this->filename);
if (fileIn.open(QIODevice::ReadOnly))
{
QDataStream in(&fileIn);
in.setVersion(QDataStream::Qt_4_6);
in >> hash;
fileIn.close();
}
}
QVariant PersistentData::getParameter(const QString & key) const {
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::getParameter() key = " << key << " value = " << hash.value(key).toString();
#endif
return hash.value(key);
}
QVariant PersistentData::getParameter(const QString & key)
{
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::getParameter() key = " << key << " value = " << hash.value(key).toString();
#endif
return hash.value(key);
}
void PersistentData::setParameter(const QString & key, QVariant value)
{
this->isChangedFlag = true;
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::setParameter() key = " << key << " value = " << value.toString();
#endif
this->hash.insert(key, value);
}
void PersistentData::clearParameter(const QString & key)
{
this->isChangedFlag = true;
this->hash.remove(key);
}
bool PersistentData::hasParameter(const QString & key) const
{
return hash.contains(key);
}
uint PersistentData::getUintParameter(const QString & key) const
{
qDebug() << "PersistentData::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;
}
QList<QString> PersistentData::uniqueKeys() const {
return hash.uniqueKeys();
}
void PersistentData::setDCFirmwareVersion(const QString & fw_version)
{
// there must be a version string!
if (fw_version.size() < 1) return;
if (this->hash["dc_fw_version"].toString() != fw_version) {
this->isChangedFlag = true;
this->hash.insert("dc_fw_version", fw_version);
}
}
QString PersistentData::getDCFirmwareVersion()
{
return this->hash["dc_fw_version"].toString();
}

View File

@ -1,49 +0,0 @@
#ifndef PERSISTENTDATA_H
#define PERSISTENTDATA_H
#include <QObject>
#include <QHash>
#include <QVariant>
#include <QList>
#include <QString>
class PersistentData : public QObject
{
Q_OBJECT
public:
explicit PersistentData(const QString &datafileName, QObject *parent = nullptr);
void setDCFirmwareVersion(const QString & fw_version);
QString getDCFirmwareVersion();
QVariant getParameter(const QString & key);
QVariant getParameter(const QString & key) const;
void setParameter(const QString & key, QVariant value);
void clearParameter(const QString & key);
bool hasParameter(const QString & key) const;
uint getUintParameter(const QString & key) const;
QList<QString> uniqueKeys() const;
public slots:
void serializeToFile();
signals:
private:
QHash<QString, QVariant> hash;
QString dc_fw_version;
QString filename;
void save();
void read();
bool isChangedFlag;
};
#endif // PERSISTENTDATA_H

View File

@ -1,181 +0,0 @@
#include "Ticket.h"
#include <QDebug>
Ticket::Ticket(TICKET_VARIANT ticketVariant, QObject *parent )
: QObject(parent)
, ticketVariant(ticketVariant)
, _hasTemplateDynData(false)
{
}
TICKET_VARIANT Ticket::variant()
{
return this->ticketVariant;
}
QList<quint8> * Ticket::templateList()
{
return &(this->_templateList);
}
bool Ticket::hasTemplateDynData()
{
return this->_hasTemplateDynData;
}
quint8 Ticket::getCurrentProcessedTemplateNumber()
{
return this->currentProcessedTemplateNumber;
}
void Ticket::setCurrentTemplateProcessed()
{
this->currentProcessedTemplateNumber++;
}
bool Ticket::initNew(TICKET_VARIANT ticketVariant, const QList<quint8> & templateList, const QHash<QString, QVariant> & printingData)
{
this->clear();
this->ticketVariant = ticketVariant;
this->printingData = printingData;
this->_templateList = templateList;
this->currentProcessedTemplateNumber = 0;
// DEBUG
qCritical() << "Ticket::initNew():";
qCritical() << " -> " << ticketVariant;
int multiplicatorInt = 1; // default
switch (this->ticketVariant) {
case TICKET_VARIANT::PARKING_TICKET:
break;
case TICKET_VARIANT::RECEIPT:
break;
case TICKET_VARIANT::ERROR_RECEIPT:
break;
case TICKET_VARIANT::START_RECEIPT:
this->_templateList << 21 << 22 << 23;
break;
case TICKET_VARIANT::STOP_RECEIPT:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FINE_PAYMENT:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FREE_TICKET:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FOOD_STAMP:
if (printingData.contains("dyn1_list")) {
this->_hasTemplateDynData = true;
this->dyn1List = printingData["dyn1_list"].toStringList();
this->dyn2List = printingData["dyn2_list"].toStringList();
}
if (printingData.contains("multiplicator")) {
multiplicatorInt = printingData["multiplicator"].toInt();
for (int i = 1; i < multiplicatorInt; i++) {
this->_templateList << 1;
}
// last template:
this->_templateList << 2;
}
// DEBUG FOOD_STAMP:
qCritical() << " --> printingData[\"multiplicator\"]" << multiplicatorInt;
break;
}
// DEBUG
QString templateListString;
for (int i =0; i < this->_templateList.size(); ++i) {
templateListString.append(QString(" %1").arg(this->_templateList.at(i)));
}
qCritical() << " -> templates: " << templateListString;
return true;
}
void Ticket::clear()
{
this->ticketVariant = TICKET_VARIANT::PARKING_TICKET;
this->printingData.clear();
this->_templateList.clear();
this->errorCode.clear();
this->errorDescription.clear();
this->_hasTemplateDynData = false;
this->dyn1List.clear();
this->dyn1List.clear();
}
QString Ticket::getErrorCode() { return this->errorCode; }
QString Ticket::getErrorDescription() { return this->errorDescription; }
/**
*/
QStringList Ticket::getDyn1List()
{
return this->dyn1List;
}
QStringList Ticket::getDyn2List()
{
return this->dyn2List;
}
QHash<QString, QVariant> & Ticket::getPrintingData()
{
return this->printingData;
}
/************************************************************************************************
* operator
*
*/
QDebug operator<<(QDebug debug, TICKET_VARIANT ticketVariant)
{
switch (ticketVariant) {
case TICKET_VARIANT::PARKING_TICKET:
debug << "TICKET_VARIANT::PARKING_TICKET";
break;
case TICKET_VARIANT::RECEIPT:
debug << "TICKET_VARIANT::RECEIPT";
break;
case TICKET_VARIANT::ERROR_RECEIPT:
debug << "TICKET_VARIANT::ERROR_RECEIPT";
break;
case TICKET_VARIANT::START_RECEIPT:
debug << "TICKET_VARIANT::START_RECEIPT";
break;
case TICKET_VARIANT::STOP_RECEIPT:
debug << "TICKET_VARIANT::STOP_RECEIPT";
break;
case TICKET_VARIANT::FINE_PAYMENT:
debug << "TICKET_VARIANT::FINE_PAYMENT";
break;
case TICKET_VARIANT::FOOD_STAMP:
debug << "TICKET_VARIANT::FOOD_STAMP";
break;
case TICKET_VARIANT::FREE_TICKET:
debug << "TICKET_VARIANT::FREE_TICKET";
break;
}
return debug;
}

View File

@ -1,88 +0,0 @@
#ifndef TICKET_H
#define TICKET_H
#include <QObject>
#include <QHash>
#include "../DeviceControllerInterface.h"
using namespace nsDeviceControllerInterface;
QDebug operator<<(QDebug debug, TICKET_VARIANT ticketVariant);
class Ticket : public QObject
{
Q_OBJECT
public:
Ticket(TICKET_VARIANT ticketVariant, QObject *parent = nullptr);
bool initNew(TICKET_VARIANT ticketVariant, const QList<quint8> & templateList, const QHash<QString, QVariant> & printingData);
void clear();
TICKET_VARIANT variant();
QList<quint8> * templateList();
/**
* @brief getPrintingData - generic getter for printingData
* Used mainly for simple tickets (single tickets e.g. ParkingTicket)
* @return
*/
QHash<QString, QVariant> & getPrintingData();
/**
* @brief hasTemplateDynData
* @return true, if ticket has dynamic data for each template.
*
* This depends on TICKET_VARIANT and printingData
*/
bool hasTemplateDynData();
/**
* @brief getDyn1List
* contains dynamic template data
* The size of the lists must be exactly the same as the number of templates.
*/
QStringList getDyn1List();
QStringList getDyn2List();
quint8 getCurrentProcessedTemplateNumber();
/**
* Mark current template as processed
*/
void setCurrentTemplateProcessed();
// error handling
QString getErrorCode();
QString getErrorDescription();
private:
TICKET_VARIANT ticketVariant;
// printingData from application
QHash<QString, QVariant> printingData;
// templateList, from .ini or created by ticketVariant...
QList<quint8> _templateList;
bool _hasTemplateDynData;
quint8 currentProcessedTemplateNumber;
QStringList dyn1List;
QStringList dyn2List;
// error handling
QString errorCode;
QString errorDescription;
};
#endif // TICKET_H

View File

@ -1,26 +0,0 @@
#include "TicketUtils.h"
#include <QLocale>
#include <QDate>
TicketUtils::TicketUtils(QObject *parent) : QObject(parent)
{
}
QString TicketUtils::getLocaleDateString(const QLocale & qLocale, const QDate & qDate)
{
QString dateString;
if (qLocale.language() == QLocale::Lithuanian) {
// QLocale::ShortFormat produces date string: "yyyy-mm-dd" ...
// this is to long for the printer.
dateString = qDate.toString("yy-MM-dd");
}
else {
dateString = qLocale.toString(qDate, QLocale::ShortFormat);
}
return dateString;
}

View File

@ -1,34 +0,0 @@
#ifndef TICKETUTILS_H
#define TICKETUTILS_H
#include <QObject>
class TicketUtils : public QObject
{
Q_OBJECT
public:
explicit TicketUtils(QObject *parent = nullptr);
/**
* @brief getLocaleDateString
* @param qLocale
* @param qDate
* @return a localized date string short format
*
* Note QLocale::ShortFormat does not result to the
* string we need for ticket printing therefore this
* helper method was created.
*
* e.g. using Lithuanian (lt_LT) we get a date in short format:
* "2024-08-08" unfortunately this is to long, we need
* the year with only two digits.
* e.g. in German (de_DE) it is enought: "08.08.24"
*
*/
static QString getLocaleDateString(const QLocale &qLocale, const QDate &qDate);
signals:
};
#endif // TICKETUTILS_H

429
src/com.cpp Normal file
View File

@ -0,0 +1,429 @@
#include "com.h"
#include <QDebug>
//#include "controlBus.h"
//////////////////////////////////////////////////////////////////////////////////
///
/// serial hardware layer
///
//////////////////////////////////////////////////////////////////////////////////
static int64_t com_want2read;
// -------------------------------------------------------------------------------------------------------------
// --------- PUBLIC --------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength)
{
sendBuffer=data;
sendLen=sendLength;
if (CatSerial->isOpen())
{
//qDebug() << "sending..." << sendBuffer;
CatSerial->write(sendBuffer);
} else
qDebug() << "error sending, port is not open";
}
bool T_com::readFromSerial(QByteArray &data, uint16_t &sendLength)
{
// return one time true if new data (completly) read.
// return new data in &data and &sendLength to other objects
uint16_t ll=rawInLen;
if (!CatSerial->isOpen())
return false;
data.clear();
data.append(rawInput);
sendLength=ll;
rawInLen=0; // beim 2. Aufruf 0 zurück weil nichts neues da
if (ll>0)
return true;
return false;
}
// -------------------------------------------------------------------------------------------------------------
// --------- PRIVATES --------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
T_com::T_com(QWidget *parent) : QMainWindow(parent)
{
// port settings come from tabCom->Sdata->serial
gpi_serialChanged();
CatSerial = new QSerialPort(); // PortHW object for Control&Analyse Tool
//CatSerial->clear();
//CatSerial->clearError();
connect(CatSerial, &QSerialPort::readyRead, this, &T_com::readSomeBytes);
// still reading, not sure if complete, undefined number of calls while reading
connect(CatSerial, &QSerialPort::bytesWritten, this, &T_com::serialSendComplete);
// system confirms sending complete
//connect(CatSerial, &QSerialPort::dataTerminalReadyChanged, this, &T_com::incomingWake);
//connect(CatSerial, &QSerialPort::requestToSendChanged, this, &T_com::incomingWake);
// timer detects time gap in input flow
serRecTime = new QTimer();
connect(serRecTime, SIGNAL(timeout()), this, SLOT(receiveTO()));
serRecTime->setSingleShot(true); // single shot! only one impulse if receive complete
serRecTime->stop(); // on hold
// check COM-TAB periodic if user wants to connect or disconnect
QTimer *ChkConnectTimer = new QTimer();
connect(ChkConnectTimer, SIGNAL(timeout()), this, SLOT(ser_ISR100ms()));
ChkConnectTimer->setSingleShot(false);
ChkConnectTimer->start(100); // in ms
com_want2read=0;
}
T_com::~T_com()
{
if (CatSerial->isOpen())
CatSerial->close();
}
void T_com::ser_ISR100ms()
{
// call every 100ms to check if user(HMI) wants to connect or disconnect
//qDebug() << "~~>LIB" << "checking connect button... " ;
uint8_t chkConn = gpi_getSerialConn(); // from global GUI buffer (Sdata)
switch (chkConn)
{
case 0: // 0 button "connect" was just released
closeSerialPort();
gpi_serialChanged(); // set chkConn to 2, thus getting edge
break;
case 1: // 1 button "connect" was just pressed
open_Serial_Port();
gpi_serialChanged(); // set chkConn to 2, thus getting edge
break;
}
if (CatSerial->isOpen())
gpi_serialIsOpen(true);
else
gpi_serialIsOpen(false);
}
// -------------------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
char T_com::open_Serial_Port()
{
bool ret;
QString myString=nullptr, myPortName=nullptr, myBaudStr=nullptr;
int myBaudNr;
if (CatSerial->isOpen())
return 0; // opening twice is not allowed
//qDebug() << "connecting..." << myPortName;
myPortName=gpi_getComPortName(); // was selected and stored from GUI
CatSerial->setPortName(myPortName);
myBaudNr=gpi_getBaudNr(); // was selected and stored from GUI
switch (myBaudNr)
{
// 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200
case 0: CatSerial->setBaudRate(QSerialPort::Baud1200); myBaudStr="1200"; break;
case 1: CatSerial->setBaudRate(QSerialPort::Baud9600); myBaudStr="9600"; break;
case 2: CatSerial->setBaudRate(QSerialPort::Baud19200); myBaudStr="19200"; break;
case 3: CatSerial->setBaudRate(QSerialPort::Baud38400); myBaudStr="38400"; break;
case 4: CatSerial->setBaudRate(QSerialPort::Baud57600); myBaudStr="57600"; break;
case 5: CatSerial->setBaudRate(QSerialPort::Baud115200); myBaudStr="115200"; break;
}
CatSerial->setDataBits(QSerialPort::Data8);
// alt: QSerialPort::Data5,6,7,8
CatSerial->setParity(QSerialPort::NoParity);
// alt: EvenParity, OddParity, NoParity
CatSerial->setStopBits(QSerialPort::OneStop);
// alternative: OneStop, TwoStop, OneAndHalfStop
CatSerial->setFlowControl(QSerialPort::NoFlowControl);
// alt: HardwareControl, SoftwareControl, NoFlowControl
ret=CatSerial->open(QIODevice::ReadWrite);
// alt: QIODevice::ReadWrite QIODevice::ReadOnly QIODevice::WriteOnly
if (!ret)
{
myString.clear();
myString = "error ";
myString.append(CatSerial->errorString());
qDebug() << myString;
gpi_setTxt4comStateLine(myString);
return 0;
} else
{
myString.clear();
myString.append(myPortName);
//lang=myString.size();
myString.append(" opened with ");
myString.append(myBaudStr);
myString.append(" 8N1");
qDebug() << myString;
gpi_setTxt4comStateLine(myString);
gpi_setTxt4RsDiagWin(myString+"\n");
}
return 0;
}
void T_com::closeSerialPort()
{
if (CatSerial->isOpen())
{
qDebug() << "closing connection";
CatSerial->close();
gpi_setTxt4comStateLine("closed");
gpi_setTxt4RsDiagWin("closed");
}
}
void T_com::readSomeBytes(void)
{
// called by serial-read-detection
// restart off-time as input flow is ongoing
// timer for slow receive
// and serves as timeout for fast receive is msg is shorter as expected
serRecTime->stop();
serRecTime->start(20); // in ms
//qDebug()<< "com-rec read some bytes";
this->receiveByLength(); // since 14.12.21: fast receive
}
void T_com::receiveFixLen(int64_t nrOfbytesToReceive)
{
// call this before sending a request to slave
// then we know exactly when reception is complete -> much faster
com_want2read=nrOfbytesToReceive;
// since 14.12.21: FastDevice Protocol has two lengthen:
// fast: 12byte reception long: 68byte
}
void T_com::receiveByLength(void)
{
if (CatSerial->isOpen())
{
QString myString=nullptr, tmpStr=nullptr;
int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes
//qDebug()<< "com-rec current Len: "<< nrOfBytesreceived;
if (nrOfBytesreceived >= com_want2read)
{
QByteArray data = CatSerial->readAll(); // erst auslesen wenn alles da! löscht den Empfangspuffer
serRecTime->stop(); // stop timeout to avoid 2nd emit
rawInLen=uint16_t (nrOfBytesreceived);
rawInput.clear();
rawInput.append(data);
// report "new data received" to other objects
//qDebug()<< "com-recFinished by Len "<< rawInLen;
emit receivingFinished();
}
}
}
void T_com::receiveTO(void)
{
// no new input data for 20ms, --> assuming frame complete
// save data in private "rawInput"-buffer
if (CatSerial->isOpen())
{
QString myString=nullptr, tmpStr=nullptr;
int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes
QByteArray data = CatSerial->readAll();
rawInLen=uint16_t (nrOfBytesreceived);
rawInput.clear();
rawInput.append(data);
//rawInput[rawInLen]=0; // Zwangsterminierung bei QByteArray nicht nötig
// diag display in serial in/out window and debug window
myString.clear();
myString.setNum(rawInLen);
myString.append(" in: ");
//myString.append(rawInput);
for (int ii=0; ii<rawInLen; ii++)
{
tmpStr.clear();
tmpStr.setNum(rawInput[ii],16); // problem: wenn >0x80 dann wird EIN Byte 16 stellig angezeigt
int ll=tmpStr.length();
if (ll>2)
{
myString.append(tmpStr[ll-2]);
myString.append(tmpStr[ll-1]);
} else
{
myString.append(tmpStr);
}
myString.append(" ");
}
myString.append("\n");
#ifdef PRINTALLDEBUGS
qDebug() << "VCP:" << myString; // display all inputs and outputs in output window
#endif
gpi_setTxt4RsDiagWin(myString);
//gpi_set2ndTxt4RsDiagWin(myString);
// report "new data received" to other objects
//qDebug()<< "com-recFinished by TO";
emit receivingFinished();
}
}
void T_com::serialSendComplete(void)
{
// system confirms sending complete, diag display
QString myString=nullptr, tmpStr=nullptr;
myString.clear();
myString.setNum(sendLen);
myString.append(" out: ");
for (int ii=0; ii<sendLen; ii++)
{
tmpStr.clear();
tmpStr.setNum(sendBuffer[ii],16); // problem: wenn >0x80 dann 16stellig
int ll=tmpStr.length();
if (ll>2)
{
//qDebug() << "long_string" << ll << "\n";
myString.append(tmpStr[ll-2]);
myString.append(tmpStr[ll-1]);
} else
{
myString.append(tmpStr);
}
myString.append(" ");
}
#ifdef PRINTALLDEBUGS
myString.append("\n");
qDebug() << myString; // display all output data in out-window
#endif
gpi_setTxt4RsDiagWin(myString);
emit sendingFinished(); // for whom it may interest
}
bool T_com::isPortOpen(void)
{
if (CatSerial->isOpen())
return true;
return false;
}
// -------------------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------
/*
uint8_t T_com::getAllPortPins(void)
{
uint8_t rs232pins=0;
rs232pins= uint8_t(CatSerial->pinoutSignals());
// rs232pins: all signals bitwise coded in one byte:
// readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output)
// unused inputs: bit1=RxD bit 3=DCD bit 5 = RING
// handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80)
//qDebug()<<"serial port pins: " << rs232pins;
return rs232pins;
}
bool T_com::getHSin_CTS(void)
{
// return the used Handshake IN (CTS, alt. DSR): true= high level (+8V)
uint8_t rs232pins=0;
rs232pins= uint8_t(CatSerial->pinoutSignals());
// rs232pins: all signals bitwise coded in one byte:
// readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output)
// unused inputs: bit1=RxD bit 3=DCD bit 5 = RING
// handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80)
if (rs232pins & 0x80) // CTS
return true;
return false;
}
bool T_com::getHSin_DSR(void)
{
uint8_t rs232pins=0;
rs232pins= uint8_t(CatSerial->pinoutSignals());
if (rs232pins & 0x10) // DSR
return true;
return false;
}
void T_com::incomingWake(void) //(bool LevelOfTheBit)
{
emit wasWokenBySerialHandshake();
}
bool T_com::setHSout_RTS(bool hsout)
{
// hsout true=positiv voltage +12V false= -12V
// retval: true=setting OK
bool cc;
// 10.5.19, am Windows-PC nachgemessen, funktioniert gut
// false ergibt -12V true ergibt +12V
cc=CatSerial->setRequestToSend(hsout); // RTS out
// retval true means "setting was successful"
// alternative: use DTR as Handshake:
//cc=CatSerial->setDataTerminalReady(false); // DTR out
// retval true means "setting was successful"
//qDebug()<<"RTS " <<cc;
return cc;
}
bool T_com::setHSout_DTR(bool hsout)
{
// hsout true=positiv voltage +12V false= -12V
// retval: true=setting OK
bool cc;
// 10.5.19, am Windows-PC nachgemessen, funktioniert gut
// false ergibt -12V true ergibt +12V
cc=CatSerial->setDataTerminalReady(hsout); // DTR out
// retval true means "setting was successful"
//qDebug()<<"DTR " <<cc;
return cc;
}
*/

499
src/controlBus.cpp Normal file
View File

@ -0,0 +1,499 @@
#include <stdint.h>
#include <QString>
#include <QDebug>
#include "tslib.h"
//#include "controlBus.h"
// ///////////////////////////////////////////////////////////////////////////////////
// control serial interface gui <--> serial
// ///////////////////////////////////////////////////////////////////////////////////
static QString rs_comportName; // z.B. "COM48"
static QString rs_baudStr; // z.B. "19200"
static int rs_baudNr; //0...5 oder -1
static uint8_t rs_connect; // 0,1
void epi_setSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect)
{
rs_comportName = ComName;
rs_baudStr = BaudStr;
rs_baudNr = BaudNr; // 0=1200 1=9600 2=19200 3=38400 4=57600 5=115200 oder -1
rs_connect = connect; // 0/1
}
void epi_closeSerial(void)
{
rs_connect=0;
}
void gpi_serialChanged(void)
{
// serial confirms that port was closed or opened
rs_connect=2; // Flanke, nur 1x öffnen/schließen
}
uint8_t gpi_getSerialConn(void)
{
return rs_connect;
}
int gpi_getBaudNr(void)
{
return rs_baudNr;
}
QString gpi_getComPortName(void)
{
return rs_comportName;
}
static bool rs_portIsOpen;
void gpi_serialIsOpen(bool offen)
{
rs_portIsOpen=offen;
}
bool epi_isSerialPortOpen()
{
// true: port is open false: port is closed
return rs_portIsOpen;
}
// ///////////////////////////////////////////////////////////////////////////////////
// Control transfer gui <--> serial
// ///////////////////////////////////////////////////////////////////////////////////
static char AutoEmissionOn; // 1: zyklisch Anfragen zum Slave senden
void epi_startEmmision(char start)
{
AutoEmissionOn=start;
}
bool gpi_isEmmisionOn(void)
{
return AutoEmissionOn;
}
//-----------------------------------------------------
static uint16_t datif_sendingPeriod;
static bool datif_sendingPer_changed;
uint16_t gpi_getPeriodicSendTimeVal()
{
datif_sendingPer_changed=0;
if (datif_sendingPeriod<3 || datif_sendingPeriod>10000)
return 130; // ms, default
else
return datif_sendingPeriod;
}
void epi_setPeriodicSendTimeVal(uint16_t val)
{
if (val>=3 && val<10000)
{
datif_sendingPer_changed=1;
datif_sendingPeriod=val;
}
}
bool gpi_PeriodicSendTimeHasChanged()
{
return datif_sendingPer_changed;
}
//-----------------------------------------------------
//-----------------------------------------------------
// ///////////////////////////////////////////////////////////////////////////////////
// Status Display gui <--> serial
// ///////////////////////////////////////////////////////////////////////////////////
// linke Spalte, über Connect Button
static QString txt4comStateLine;
QString epi_getTxt4comStateLine(void)
{
// GUI: get Text for serial Comport-State Line
return txt4comStateLine;
}
void gpi_setTxt4comStateLine(QString txtline) // gpi
{
// serial: write Text to be displayed in serial Comport-State line (like "connected")
txt4comStateLine.clear();
if (txtline=="")
txt4comStateLine.clear();
else
txt4comStateLine=txtline;
}
void epi_clrTxt4comStateLine()
{
txt4comStateLine.clear();
}
//---------------------------------------------------------------------------------------------
// rechte Spalte, oberste Statuszeile
// I) "Handshakes" (serial Control) flow.cpp
// geht überhaupt was raus? kommt überhaupt was zurück?
static QString txt4HsStateLine;
QString epi_getTxt4HsStateLine(void)
{
return txt4HsStateLine;
}
void gpi_setTxt4HsStateLine(QString txtline)
{
txt4HsStateLine.clear();
if (txtline=="")
txt4HsStateLine.clear();
else
txt4HsStateLine=txtline;
}
void epi_clrTxt4HsStateLine()
{
txt4HsStateLine.clear();
}
//---------------------------------------------------------------------------------------------
// II) Master receive state (empfangenes Telgramm OK? crc? length? )
// Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp)
static QString txt4masterStateLine;
QString epi_getTxt4masterStateLine(void)
{
return txt4masterStateLine;
}
void gpi_setTxt4masterStateLine(QString txtline)
{
txt4masterStateLine.clear();
if (txtline=="")
txt4masterStateLine.clear();
else
txt4masterStateLine=txtline;
}
void epi_clrTxt4masterStateLine()
{
txt4masterStateLine.clear();
}
//---------------------------------------------------------------------------------------------
// III Slave receive (from Master) OK? if then show results, if not then show errors
// entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR
// Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch
// nicht verwenden und nichts ausgeben oder einlesen
static QString txt4resultStateLine;
QString epi_getTxt4resultStateLine(void)
{
return txt4resultStateLine;
}
void gpi_setTxt4resultStateLine(QString txtline)
{
txt4resultStateLine.clear();
if (txtline=="")
txt4resultStateLine.clear();
else
txt4resultStateLine=txtline;
}
void epi_clrTxt4resultStateLine()
{
txt4resultStateLine.clear();
}
//---------------------------------------------------------------------------------------------
// IV Statuszeile Empfangsdaten
static QString txt4dataLine;
QString epi_getTxt4dataStateLine(void)
{
// GUI: get Text for serial Comport-State Line
return txt4dataLine;
}
void gpi_setTxt4dataStateLine(QString txtline)
{
// serial: write Text to be displayed in serial Comport-State line (like "connected")
txt4dataLine.clear();
if (txtline=="")
txt4dataLine.clear();
else
txt4dataLine=txtline;
}
void epi_clrTxt4dataStateLine()
{
txt4dataLine.clear();
}
//---------------------------------------------------------------------------------------------
// 5. Zeile: Datif Ergebnis, Daten brauchbar?
static QString txt4datifReceive;
QString epi_getTxt4datifLine(void)
{
return txt4datifReceive;
}
void gpi_setTxt4datifLine(QString txtline)
{
txt4datifReceive.clear();
if (txtline=="")
txt4datifReceive.clear();
else
txt4datifReceive=txtline;
}
void epi_clrTxt4datifLine()
{
txt4datifReceive.clear();
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
static QString txt4diagWindow;
QString epi_getTxt4RsDiagWin(void)
{
return txt4diagWindow;
}
void gpi_setTxt4RsDiagWin(QString txtline)
{
txt4diagWindow.clear();
if (txtline=="")
txt4diagWindow.clear();
else
txt4diagWindow=txtline;
}
void epi_clrTxt4RsDiagWin()
{
txt4diagWindow.clear();
}
//---------------------------------------------------------------------------------------------
static QString sndTxt4diagWindow;
QString epi_get2ndTxt4RsDiagWin(void)
{
return sndTxt4diagWindow;
}
void gpi_set2ndTxt4RsDiagWin(QString txtline)
{
sndTxt4diagWindow.clear();
if (txtline=="")
sndTxt4diagWindow.clear();
else
sndTxt4diagWindow=txtline;
}
void epi_clr2ndTxt4RsDiagWin()
{
sndTxt4diagWindow.clear();
}
// ///////////////////////////////////////////////////////////////////////////////////
// Memory for Slave responses, common data
// ///////////////////////////////////////////////////////////////////////////////////
static bool Sdata_serialTestResult;
void gpi_storeResult_serialTestOK(bool wasOk)
{
Sdata_serialTestResult=wasOk;
}
bool epi_getResult_serialTestOK()
{
// retval: true: test was successful, got right response
return Sdata_serialTestResult;
}
// ///////////////////////////////////////////////////////////////////////////////////
// Store received data for hwapi
// ///////////////////////////////////////////////////////////////////////////////////
static uint8_t Sdata_pProtResultOk;
void gpi_startNewRequest()
{
Sdata_pProtResultOk=0;
}
void gpi_storeResultOfLastRequest(bool answisok)
{
if (answisok)
Sdata_pProtResultOk=1;
else
Sdata_pProtResultOk=2;
}
uint8_t epi_getResultOfLastRequest()
{
// retval: 0: in progress 1: OK 2: error
return Sdata_pProtResultOk;
}
static uint16_t Sdata_receivedDataLength;
static uint8_t Sdata_receivedDataBlock[64];
void gpi_storeRecPayLoad(uint8_t RdDlen, uint8_t *receivedData)
{
Sdata_receivedDataLength=uint16_t(RdDlen);
if (Sdata_receivedDataLength>64)
Sdata_receivedDataLength=64;
tslib_strclr(Sdata_receivedDataBlock,0,64);
tslib_strcpy(receivedData, Sdata_receivedDataBlock, Sdata_receivedDataLength);
}
uint16_t epi_getLastPayLoad(uint16_t plBufSiz, uint8_t *payLoad)
{
// get data back in *pl, max 64 byte
// retval = nr of bytes received. If host buffer too small then
// only plBufSíz bytes are copied to pl
// plBufSíz=size of host buffer
uint16_t ml=plBufSiz;
if (ml>64) ml=64;
if (Sdata_receivedDataLength<ml)
ml=Sdata_receivedDataLength;
tslib_strcpy(Sdata_receivedDataBlock, payLoad, ml);
return Sdata_receivedDataLength;
}
static uint8_t ndbs, pari, nsb, br;
void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits,
uint8_t parity, uint8_t NrStopBits)
{
// store numbers
ndbs=NrDataBits;
pari=parity;
nsb=NrStopBits;
br=slaveBaudRate;
}
void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits,
uint8_t *parity, uint8_t *NrStopBits)
{
*NrDataBits=ndbs;
*parity=pari;
*NrStopBits=nsb;
*slaveBaudRate=br;
}
/*
void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits,
uint8_t parity, uint8_t NrStopBits) {
// store numbers
SharedMemBuffer::write()->ndbs = NrDataBits;
SharedMemBuffer::write()->pari = parity;
SharedMemBuffer::write()->nsb = NrStopBits;
SharedMemBuffer::write()->br = slaveBaudRate;
}
void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits,
uint8_t *parity, uint8_t *NrStopBits) {
*NrDataBits = SharedMemBuffer::read()->ndbs;
*parity = SharedMemBuffer::read()->pari;
*NrStopBits = SharedMemBuffer::read()->nsb;
*slaveBaudRate = SharedMemBuffer::read()->br;
}
*/
QString epi_getSlaveParamSTR()
{
QString mySt;
char ctmp;
// uint8_t ndbs;
// uint8_t pari;
// uint8_t nsb;
// uint8_t br;
mySt.clear();
// br=SharedMemBuffer::read()->br;
// ndbs=SharedMemBuffer::read()->ndbs;
// pari =SharedMemBuffer::read()->pari;
// nsb=SharedMemBuffer::read()->nsb;
switch (br)
{
case 1: mySt="1200 ";break;
case 2: mySt="9600 ";break;
case 3: mySt="19200 ";break;
case 4: mySt="38400 ";break;
case 5: mySt="57600 ";break;
case 6: mySt="115200 ";break;
}
ctmp=ndbs;
ctmp+=0x30;
mySt.append(ctmp);
ctmp=pari;
mySt.append(ctmp);
ctmp=nsb;
ctmp+=0x30;
mySt.append(ctmp);
//mySt="Hallo";
return mySt;
}

1890
src/datIf.cpp Normal file

File diff suppressed because it is too large Load Diff

943
src/datei.cpp Normal file
View File

@ -0,0 +1,943 @@
// written by Thomas Sax, Jan.2022
#include "datei.h"
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ create csv file -------------------------------
// -------------------------------------------------------------------------------------------------
QByteArray datei_writeArray, datei_tempArray;
void csv_startCreatingFile(void)
{
datei_writeArray.clear();
datei_tempArray.clear();
}
void csv_addTextToFile(QString myText)
{
datei_writeArray.append(myText.toLatin1());
datei_writeArray.append(FILESEPERATOR);
}
void csv_addIntToFile(int myValue)
{
//qulonglong ullt=12345678901234567890; // max 1,844 x10^19
datei_tempArray.setNum(myValue,10); // accepted types: short, ushort, int, uint,
// qlonglong, qulonglong, float, double
// numerbase can be 2...36(!),10=dec
datei_writeArray.append(datei_tempArray);
datei_writeArray.append(FILESEPERATOR);
}
void csv_addUintToFile(uint myValue)
{
datei_tempArray.setNum(myValue,10);
datei_writeArray.append(datei_tempArray);
datei_writeArray.append(FILESEPERATOR);
}
void csv_addLongvalToFile(qlonglong myValue)
{
datei_tempArray.setNum(myValue,10);
datei_writeArray.append(datei_tempArray);
datei_writeArray.append(FILESEPERATOR);
}
void csv_addUlongvalToFile(qulonglong myValue)
{
datei_tempArray.setNum(myValue,10);
datei_writeArray.append(datei_tempArray);
datei_writeArray.append(FILESEPERATOR);
}
/*
void csv_addCurrentTimeToFile(void)
{
uint8_t hour, minute, sec, ui8buf[20];
char buf[20];
config_getSysTime(&hour, &minute, &sec);
GetTimeString(hour, minute, sec, 0, 1, ui8buf);
for (uint8_t nn=0; nn<20; nn++)
buf[nn]=char(ui8buf[nn]);
datei_writeArray.append(buf,8); // time string
datei_writeArray.append(FILESEPERATOR);
}
void csv_addCurrentDateToFile(void)
{
uint16_t year;
uint8_t month, day, ui8buf[20];
char buf[20];
config_getSystemDate(&year, &month, &day);
//qDebug()<<"date year: "<<year;
GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf);
for (uint8_t nn=0; nn<20; nn++)
buf[nn]=char(ui8buf[nn]);
datei_writeArray.append(buf, 10); // date string
datei_writeArray.append(NEWLINEINFILE);
}
*/
void csv_addNewlineToFile(void)
{
datei_writeArray.chop(1); // Komma weg
datei_writeArray.append(NEWLINEINFILE);
}
QByteArray csv_readbackArray(void)
{
return datei_writeArray;
}
/*
QByteArray csv_writeContent_testValues(void)
{
QByteArray myBA, tmpBA;
uint8_t modCount=5, modAddr=23;
uint8_t hour, minute, sec, month, day, ui8buf[20];
uint16_t year, modType=45678;
char buf[20];
uint32_t modNrDIs=1234567890;
uint8_t modNrAIs=4, modNrCtr=2, modNrDOs=8;
int modNrAOs=-2;
myBA.clear();
tmpBA.clear();
myBA.append("scan time");
myBA.append(FILESEPERATOR);
datei_getSysTime(&hour, &minute, &sec);
GetTimeString(hour, minute, sec, 0, 1, ui8buf);
for (uint8_t nn=0; nn<20; nn++)
buf[nn]=char(ui8buf[nn]);
myBA.append(buf,8); // time string
myBA.append(FILESEPERATOR);
datei_getSystemDate(&year, &month, &day);
//qDebug()<<"date year: "<<year;
GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf);
for (uint8_t nn=0; nn<20; nn++)
buf[nn]=char(ui8buf[nn]);
myBA.append(buf, 10); // date string
myBA.append(NEWLINEINFILE);
myBA.append("number of modules");
myBA.append(FILESEPERATOR);
tmpBA.setNum(modCount,10); //2nd para = number base 2, 8, 10 or 16 (bin, oct, dec, hex)
myBA.append(tmpBA);
myBA.append(NEWLINEINFILE);
myBA.append("busaddr");
myBA.append(FILESEPERATOR);
myBA.append("type");
myBA.append(FILESEPERATOR);
myBA.append("NrOfDI");
myBA.append(FILESEPERATOR);
myBA.append("NrOfAI");
myBA.append(FILESEPERATOR);
myBA.append("NrOfCtrIn");
myBA.append(FILESEPERATOR);
myBA.append("NrOfDO");
myBA.append(FILESEPERATOR);
myBA.append("NrOfAO");
myBA.append(NEWLINEINFILE);
tmpBA.setNum(modAddr,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modType,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modNrDIs,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modNrAIs,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modNrCtr,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modNrDOs,10);
myBA.append(tmpBA);
myBA.append(FILESEPERATOR);
tmpBA.setNum(modNrAOs,10);
myBA.append(tmpBA);
myBA.append(NEWLINEINFILE);
return myBA;
}
*/
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ parse csv file -------------------------------
// -------------------------------------------------------------------------------------------------
// first: QByteArray datei_readFromFile(QString filename);
uint32_t csv_nrOfEntriesInFile(QByteArray readFromFile)
{
// count sequences between FILESEPERATOR and NEWLINEINFILE
uint32_t filSize=0, pp=0;
char oneByt=0;
int filLen=readFromFile.size();
if(filLen>1)
filSize=uint32_t(filLen);
else
return 0;
// 1) find position of seperators
for (uint32_t ii=0; ii<filSize; ii++)
{
oneByt=readFromFile[ii];
if (oneByt==FILESEP1 || oneByt==FILESEP2 || oneByt==NEWLINEINFILE)
pp++;
}
// now: pp = number of seperators
// oneByt = last byte in file. If it's not a seperator then
// there's one more entry (last entry without termination)
if (oneByt !=FILESEP1 && oneByt !=FILESEP2 && oneByt !=NEWLINEINFILE)
pp++;
//qDebug()<<"csv: nr of sequences="<< pp;
return pp;
}
QByteArray csv_getOneFileSequence(QByteArray sourceFile, uint32_t sequNr)
{
// seperate file content in single sequences between FILESEPERATOR and NEWLINEINFILE
// and return "entryNr" - entry
// for this first step leave data type QByteArray
// 2nd step can change in numbers and strings
QByteArray sequence;
uint32_t sepPos[MAXNUMBEROFSEQUENCES];
uint32_t filSize=0, pp=0, ii, start=0, ende=0;
char oneByt;
int filLen, mm;
filLen=sourceFile.size();
//qDebug()<<"fillen="<< filLen;
if(filLen<10)
return "";
filSize=uint32_t(filLen);
if (sequNr>MAXNUMBEROFSEQUENCES)
return "";
// 1) find position of seperators
for (ii=0; ii<filSize; ii++)
{
oneByt=sourceFile[ii];
if (oneByt==FILESEP1 || oneByt==FILESEP2 || oneByt==NEWLINEINFILE)
{
sepPos[pp++]=ii;
}
}
// now: pp = number of entries
//qDebug()<<"nr of seperators="<< pp;
if (sequNr>=pp)
return "";
// 2) get sequence
if (sequNr==0)
{
start=0;
ende=sepPos[sequNr];
} else
if (sequNr>0)
{
start=sepPos[sequNr-1]+1;
ende=sepPos[sequNr];
}
//qDebug()<<"datei getOneFileSequence start/ende: "<<start << " " << ende;
if (start>=ende)
return "";
//return "-err3-";
sequence.clear();
//batmp.clear();
pp=0;
for (ii=start; ii<ende; ii++)
{
mm=int(ii);
if (mm>=int(filSize))
mm=0;
oneByt=sourceFile.at(mm);
sequence.append(oneByt);
}
return sequence;
}
int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA, myVA;
int entry=0;
bool ok;
myVA.clear();
myBA = csv_getOneFileSequence(sourceFile, sequNr);
//qDebug()<<"datei getEntryAsInt, sequence: " << myBA;
entry=myBA.toInt(&ok,16);
if (ok)
{
//qDebug()<<"datei getEntryAsInt, number: " << entry;
return entry;
}
//qDebug()<<"datei getEntryAsInt, error " << myBA;
return 0;
}
int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
long entry=0;
bool ok;
entry=myBA.toLong(&ok,10);
if (ok)
return entry;
return 0;
}
uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
uint8_t entry=0;
bool ok;
entry=uint8_t(myBA.toUShort(&ok,10));
if (ok)
return entry;
return 0;
}
uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
uint16_t entry=0;
bool ok;
entry=uint16_t(myBA.toUInt(&ok,10));
if (ok)
return entry;
return 0;
}
uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
uint32_t entry=0;
bool ok;
entry=myBA.toULong(&ok,10);
if (ok)
return entry;
return 0;
}
uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
uint64_t entry=0;
bool ok;
entry=myBA.toULongLong(&ok,10);
if (ok)
return entry;
return 0;
}
QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr)
{
QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr);
QString entry;
//qDebug()<<"datei getEntryAsString, sequence: " << myBA;
entry=myBA.toStdString().c_str();
return entry;
}
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ create Json file -------------------------------
// -------------------------------------------------------------------------------------------------
/*
example
QString str = "{"
" \"Herausgeber\": \"Xema\","
" \"Nummer\": \"1234-5678-9012-3456\","
" \"Deckung\": 2e+6,"
" \"Währung\": \"EURO\","
" \"Inhaber\": {"
" \"Name\": \"Mustermann\","
" \"Vorname\": \"Max\","
" \"männlich\": true,"
" \"Hobbys\": [ \"Reiten\", \"Golfen\", \"Lesen\" ],"
" \"Alter\": 42,"
" \"Kinder\": [],"
" \"Partner\": null"
" }"
"}";
*/
QString myJsonCon;
QString tmpStr;
void json_startRecord(void)
{
myJsonCon.clear();
tmpStr.clear();
myJsonCon.append('{');
}
void json_enterIntToRecord(QString attribute, ulong i_value)
{
tmpStr.clear();
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
tmpStr.setNum(i_value);
myJsonCon.append(tmpStr);
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
void json_enterTextToRecord(QString attribute, QString txt_value)
{
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
myJsonCon.append('"');
myJsonCon.append(txt_value);
myJsonCon.append('"');
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
/*
void json_addCurrentTimeToRecord(QString attribute)
{
uint8_t hour, minute, sec, ui8buf[20];
//char buf[20];
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
myJsonCon.append('"');
datei_getSysTime(&hour, &minute, &sec);
GetTimeString(hour, minute, sec, 0, 1, ui8buf);
for (uint8_t nn=0; nn<8; nn++)
myJsonCon.append(ui8buf[nn]);
myJsonCon.append('"');
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
void json_addCurrentDateToRecord(QString attribute)
{
uint16_t year;
uint8_t month, day, ui8buf[20];
//char buf[20];
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
myJsonCon.append('"');
datei_getSystemDate(&year, &month, &day);
GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf);
for (uint8_t nn=0; nn<10; nn++)
myJsonCon.append(ui8buf[nn]);
myJsonCon.append('"');
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
*/
void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals)
{
// add array of numbers with "nrofVals" elements
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
myJsonCon.append('['); // eckig!!!
for (ulong ul=0; ul<nrofVals; ul++)
{
tmpStr.setNum(buf[ul]);
myJsonCon.append(tmpStr);
myJsonCon.append(',');
}
myJsonCon.chop(1); // Komma weg
myJsonCon.append(']'); // eckig!!!
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
void json_enterStructToRecord(QString attribute)
{
// every call must be concluded with "json_finishFile()"
myJsonCon.append('"');
myJsonCon.append(attribute);
myJsonCon.append('"');
myJsonCon.append(':');
myJsonCon.append('{'); // geschweift!!
myJsonCon.append(NEWLINEINFILE);
}
void json_finishStruct(void)
{
myJsonCon.chop(2); // remove , and \r from the end
myJsonCon.append('}');
myJsonCon.append(',');
myJsonCon.append(NEWLINEINFILE);
}
void json_finishRecord(void)
{
myJsonCon.chop(2); // remove , and \r from the end
myJsonCon.append(NEWLINEINFILE);
myJsonCon.append('}');
myJsonCon.append(NEWLINEINFILE);
}
QString json_readbackRecordStr(void)
{
return myJsonCon;
}
QByteArray json_readbackRecordBa(void)
{
return myJsonCon.toLatin1();
}
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ parse Json file -------------------------------
// -------------------------------------------------------------------------------------------------
/*
example Json File:
{"temperature":28,
"snow":"no",
"Zeit":"16_21_45",
"sunny":"12h",
"humidity":75,
"wann ":"24.01.2022",
"unterstruktur":{
"day of week":"tuesday",
"year":22,
"month":1,
"day":24},
"fast am":"Ende",
"Puffer":[8,3,9,2,10]
}
*/
// first: QByteArray datei_readFromFile(QString filename);
int json_nrOfPairsInFile(QByteArray filename)
{
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
// key value pair consisting of key (unique string) and value (QJsonValue)
int nrOfPairs=jobj.size();
qDebug() << "my Json file has got: " << nrOfPairs<< "pairs";
return nrOfPairs;
}
bool json_exists(QByteArray filename, QString searchForKey)
{
// look for "searchForKey" =name of the pair (left of : )
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchForKey))
return true;
return false;
}
bool json_remove(QByteArray filename, QString searchFor)
{
// look for "searchFor" =name of the pair (left of : ) and remove the record from file
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchFor))
{
jobj.remove(searchFor);
return true;
}
return false;
}
QString json_searchForStringInFile(QByteArray filename, QString searchFor)
{
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchFor))
{
return jobj[searchFor].toString(); // toObject(); toArray();
} else
{
//qDebug() << "pairname not found in Json file";
return "";
}
}
int json_searchForIntInFile(QByteArray filename, QString searchFor)
{
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchFor))
{
return jobj[searchFor].toInt(); // toObject(); toArray();
} else
{
//qDebug() << "number not found in Json file";
return 0;
}
}
bool json_searchForObjectInFile(QByteArray filename, QString searchFor, QJsonObject *oneObject)
{
// return an object from the json file
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchFor))
{
*oneObject = jobj[searchFor].toObject();
return true;
} else
{
//qDebug() << "Object not found in Json file";
return false;
}
}
int json_nrOfPairsInObject(QJsonObject objname)
{
int nrOfPairs=objname.size();
qDebug() << "my Json Object has got: " << nrOfPairs<< "pairs";
return nrOfPairs;
}
QString json_searchForStringInObject(QJsonObject objname, QString searchFor)
{
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
if (objname.contains(searchFor))
{
return objname[searchFor].toString();
} else
{
//qDebug() << "string not found in Json object";
return "";
}
}
int json_searchForIntInObject(QJsonObject objname, QString searchFor)
{
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
if (objname.contains(searchFor))
{
return objname[searchFor].toInt();
} else
{
//qDebug() << "number not found in Json file";
return 0;
}
}
bool json_searchForArrayInFile(QByteArray filename, QString searchFor, QJsonArray *oneArray)
{
// look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String
QJsonDocument jdoc = QJsonDocument::fromJson(filename);
QJsonObject jobj = jdoc.object();
if (jobj.contains(searchFor))
{
*oneArray = jobj[searchFor].toArray();
return true;
} else
{
//qDebug() << "Array not found in Json file";
return false;
}
}
int json_nrOfValuesInArray(QJsonArray arrayname)
{
int nrOfPairs=arrayname.size();
qDebug() << "my Json Array has got: " << nrOfPairs<< "values";
return nrOfPairs;
}
bool json_getValuesOfArray(QJsonArray arrayname, int *buf, int MaxBufferSize)
{
// assuming that the array consists of integers
/* copy to local buffer:
#define MAXNROFARRAYVALUES 100
int buf[MAXNROFARRAYVALUES], ii;
int nrOfPairs=arrayname.size();
if (nrOfPairs>MAXNROFARRAYVALUES)
nrOfPairs=MAXNROFARRAYVALUES;
for (ii=0; ii<nrOfPairs; ii++)
buf[ii]=arrayname[ii].toInt();
*/
// copy to host buffer:
bool ok=true;
int nrOfPairs=arrayname.size();
if (nrOfPairs>MaxBufferSize)
{
ok=false; // got not all
nrOfPairs=MaxBufferSize;
}
for (int ii=0; ii<nrOfPairs; ii++)
buf[ii]=arrayname[ii].toInt();
return ok;
}
/*
void datei_json_readTestFile(QString filename)
{
QByteArray my2Ba;
QString my2Str;
my2Str.clear();
my2Ba=datei_readFromFile(filename);
QJsonDocument jdoc = QJsonDocument::fromJson(my2Ba);
QJsonObject jobj = jdoc.object();
//QJsonParseError jerror;
QJsonObject myObj;
QJsonArray myArray;
// key value pair consisting of key (unique string) and value (QJsonValue)
int nrOfPairs=jobj.size();
qDebug() << "my Json file has got: " << nrOfPairs<< "pairs";
if (jobj.contains("Zeit"))
qDebug() << "my Json file: " << jobj["Zeit"].toString(); // toObject(); toArray();
else
qDebug() << "my Json file contains no Zeit";
if (jobj.contains("Humidity"))
qDebug() << "my Json file: " << jobj["humidity"].toInt();
else
qDebug() << "my Json file contains no Humidity";
if (jobj.contains("month"))
qDebug() << "my Json file: " << jobj["month"].toObject(); // anzeige QJsonObject()
else
qDebug() << "my Json file contains no month";
myObj=jobj["unterstruktur"].toObject();
qDebug() << "my unterstruktur: " << myObj["month"].toInt();
qDebug() << "my unterstruktur: " << myObj["day of week"].toString();
//if (jerror.error == QJsonParseError::NoError)
// qDebug() << "no error";
qDebug() << "my Month: " << myObj["Month"].toInt();
//if (myObj["Month"] == QJsonValue::Undefined)
// qDebug() << "no found"; geht nicht
//if (jerror.error != QJsonParseError::NoError)
// qDebug() << "no found";
myArray=jobj["Puffer"].toArray();
qDebug() << "my array " <<myArray[2].toInt();
//if (jerror.error != QJsonParseError::NoError)
// qDebug() << "no found";
if ( !jobj.contains("Puffer"))
qDebug() << "no Puffer found";
if ( !myArray.contains(20))
qDebug() << "no entry found";
} */
// -------------------------------------------------------------------------------------------------
// ------------------------------------------------------ read, write, copy files -------------------
// -------------------------------------------------------------------------------------------------
void datei_closeFile(QString filename)
{
QFile file(filename);
file.close();
}
QByteArray datei_readFromFile(QString filename)
{
//QFile file("/own/H2B/dc2.hex");
//QFile file(FILENAME_STRUCTURE);
QFile file;
file.setFileName(filename);
QByteArray myBA;
myBA.clear();
if (!file.exists())
{
qDebug()<<"file not exists";
return myBA;
} else
{
if (!file.open(QIODevice::ReadOnly) )
{
qDebug()<<"cannot open";
} else
{
//qDebug()<<"loading file with " << file.size() <<"byte";
myBA = file.readAll();
//qDebug()<<"datei read: " << myBA;
file.close();
}
}
return myBA;
}
bool datei_ifFileExists(QString filename)
{
QFile file;
file.setFileName(filename);
if (file.exists())
return true;
return false;
}
char datei_writeToFile(QString filename, QByteArray content)
{
// retval=0 if successful 1: no write access allowed 2:cannot open to append 3:cannot create new file
QFile file(filename);
QFileInfo myFI(filename);
//if (!myFI.isWritable()) //geht nur bei NTFS, weg.
//{
//file.setPermissions(filename, QFile::WriteOther); geht nicht :(
// qDebug()<<"datei_writeToFile: writing not allowed. set attributes first!";
// return 1;
//}
if (file.exists())
{
if (!file.open(QIODevice::Append))
{
qDebug()<<"datei_writeToFile cannot open to append";
return 2;
} else
{
// add new object to the end of the file
file.write(content);
file.close();
return 0; // OK
}
} else
{
if (!file.open(QIODevice::WriteOnly))
{
qDebug()<<"datei_writeToFile cannot open new";
return 3;
} else
{
qDebug()<<"create new file";
// write first lines into file
file.write(content);
file.close();
return 0; // OK
}
}
return 0;
}
bool datei_copyFile(QString currentFileName, QString newFileName)
{
// retval=true if successful
QFile file;
file.setFileName(currentFileName);
return file.copy(newFileName);
}
bool datei_clearFile(QString filename)
{
// retval=true if successful
QFile file;
file.setFileName(filename);
file.remove(); // 3.2.22 erst ganz löschen wegen Schreibrechten
if (!file.open(QIODevice::WriteOnly))
{
qDebug()<<"datei_clearFile cannot open file to delete";
return false;
} else
{
file.write(0);
file.close();
return true;
}
}

1461
src/dcBL.cpp Normal file

File diff suppressed because it is too large Load Diff

3825
src/hwapi.cpp Normal file

File diff suppressed because it is too large Load Diff

9
src/main.cpp Normal file
View File

@ -0,0 +1,9 @@
#include <QCoreApplication>
#include "tslib.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}

764
src/prot.cpp Normal file
View File

@ -0,0 +1,764 @@
#include "prot.h"
#include <QDebug>
#include "controlBus.h"
#include "dcBL.h"
T_prot::T_prot()
{
mySerialPort = new T_com();
connect(mySerialPort, SIGNAL(receivingFinished()), this, SLOT( analyseRecData() ));
//connect(mySerialPort, SIGNAL(sendingFinished()), this, SLOT(sendeFin()));
for (int nn=0; nn<FRAME_DATALEN; nn++)
{
chOut_Data[nn]=0;
ui8OutputData[nn]=0;
InputData[nn]=0;
}
for (int nn=0; nn<BL_DATA_LEN; nn++)
{
ui8BLsendData[nn]=0;
}
WriteCommand=0;
WriteAddr=0;
WrDataLength=0;
SendDataValid=0;
kindOfData=0;
slaveAddr=0;
ReadCommand=0;
ReadAddr=0;
reserve =0;
RecSlaveAddr =0;
INdataValid=0;
readSource =0;
readAddress=0;
RdDataLength=0;
BLsendDataLength=0;
}
// ---------------------------------------------------------------------------------------------------------
// sending.....
// ---------------------------------------------------------------------------------------------------------
bool T_prot::isPortOpen(void)
{
return mySerialPort->isPortOpen();
}
bool T_prot::isSerialFree(void)
{
return true; // ohne HS's kann er nicht blockiert sein
}
void T_prot::setRecLen(uint16_t WriteCmd)
{
if (WriteCmd<100)
{
RdDataLength=DATALEN_RECEIVE_LONG; // store here already because it's no longer
// returned from slave
mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_LONG);
} else
{
RdDataLength=DATALEN_RECEIVE_FAST;
mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_FAST);
}
}
void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data)
{
WriteCommand=WriteCmd;
WriteAddr=WrAddr;
WrDataLength=WrDatLen;
if (WrDataLength>FRAME_DATALEN)
WrDataLength=FRAME_DATALEN;
for (int nn=0; nn<WrDataLength; nn++)
ui8OutputData[nn]=data[nn];
SendDataValid=1; // always set WR first
kindOfData=0; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr)
{
WriteCommand=WriteCmd;
WriteAddr=WrAddr;
WrDataLength=0;
for (int nn=0; nn<FRAME_DATALEN; nn++)
ui8OutputData[nn]=0;
SendDataValid=1; // always set WR first
kindOfData=0; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserWriteData(uint16_t WriteCmd)
{
WriteCommand=WriteCmd;
WriteAddr=0;
WrDataLength=0;
for (int nn=0; nn<FRAME_DATALEN; nn++)
ui8OutputData[nn]=0;
SendDataValid=1; // always set WR first
kindOfData=0; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val)
{
// wie oben, jedoch einfachere Datenübergabe
WriteCommand=WriteCmd;
WriteAddr=WrAddr;
WrDataLength=1;
ui8OutputData[0]=val;
SendDataValid=1; // always set WR first
kindOfData=0; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1)
{
WriteCommand=WriteCmd;
WriteAddr=WrAddr;
WrDataLength=2;
ui8OutputData[0]=val0;
ui8OutputData[1]=val1;
SendDataValid=1; // always set WR first
kindOfData=0; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, char *data)
{
WriteCommand=WriteCmd;
WriteAddr=WrAddr;
WrDataLength=WrDatLen;
if (WrDataLength>FRAME_DATALEN)
WrDataLength=FRAME_DATALEN;
for (int nn=0; nn<WrDataLength; nn++)
chOut_Data[nn]=data[nn];
SendDataValid=1; // always set WR first
kindOfData=1; // 0: binaries, 1:text
this->setRecLen(WriteCmd);
}
void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr, uint16_t reserv)
{
ReadCommand=ReadCmd;
ReadAddr=RdAddr;
reserve=reserv;
SendDataValid |=2;
readAddress=RdAddr; // store here already because it's no longer returned from slave
readSource=ReadCmd;
}
void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr)
{
ReadCommand=ReadCmd;
ReadAddr=RdAddr;
reserve=0;
SendDataValid |=2;
readAddress=RdAddr; // store here already because it's no longer returned from slave
readSource=ReadCmd;
}
void T_prot::setUserReadData( uint16_t ReadCmd)
{
ReadCommand=ReadCmd;
ReadAddr=0;
reserve=0;
SendDataValid |=2;
readAddress=0; // store here already because it's no longer returned from slave
readSource=ReadCmd;
}
void T_prot::setBLsendData( uint8_t len, uint8_t *buf)
{
for (int nn=0; nn<BL_DATA_LEN; nn++)
ui8BLsendData[nn]=0;
BLsendDataLength=len;
if ( BLsendDataLength>BL_DATA_LEN) BLsendDataLength=BL_DATA_LEN;
for (int nn=0; nn<BLsendDataLength; nn++)
ui8BLsendData[nn]=buf[nn];
WriteCommand=0xFFFF;
this->setRecLen(100); // how many??
//readAddress= // needed??
//qDebug()<<"prot: got BL data " << len << "bytes, ";
//for (int i=0; i<len; ++i) {
// printf("%02x ", (unsigned char)buf[i]);
//} printf("\n");
/*
qDebug()<<buf[0] <<buf[1] <<buf[2] <<buf[3] <<buf[4] <<buf[5] <<buf[6] <<buf[7];
qDebug() <<buf[8] <<buf[9] <<buf[10] <<buf[11] <<buf[12] <<buf[13]<<buf[14]<<buf[15];
qDebug() <<buf[16] <<buf[17] <<buf[18] <<buf[19] <<buf[20] <<buf[21]<<buf[22]<<buf[23];
qDebug() <<buf[24] <<buf[25] <<buf[26] <<buf[27] <<buf[28] <<buf[29]<<buf[30]<<buf[31];
qDebug() <<buf[32] <<buf[33] <<buf[34] <<buf[35] <<buf[36] <<buf[37]<<buf[38]<<buf[39];
qDebug() <<buf[40] <<buf[41] <<buf[42] <<buf[43] <<buf[44] <<buf[45]<<buf[46]<<buf[47];
qDebug() <<buf[48] <<buf[49] <<buf[50] <<buf[51] <<buf[52] <<buf[53] <<buf[54]<<buf[55];
qDebug() <<buf[56] <<buf[57] <<buf[58] <<buf[59] <<buf[60] <<buf[61] <<buf[62]<<buf[63];
qDebug() <<buf[64] <<buf[65] <<buf[66] <<buf[67] <<buf[68] <<buf[69] <<buf[70]<<buf[71];
qDebug() <<buf[72] <<buf[73] <<buf[74] <<buf[75] <<buf[76] <<buf[77] <<buf[78]<<buf[79];
*/
}
void T_prot::receiveFixLen(int64_t nrOfbytesToReceive)
{
mySerialPort->receiveFixLen(nrOfbytesToReceive);
}
void T_prot::sendUserData(uint16_t slaveAdr)
{
// man könnte hier noch "SendDataValid" abfragen,
// muss immer 3 sein, muss man aber nicht
//qDebug() << "prot send user data "<<slaveAdr;
QByteArray packBuf_2;
slaveAddr=slaveAdr;
if (WriteCommand==0xFFFF)
{
// Bypass for bootloader, no protocol frame but send as is...
packBuf_2.clear();
for (int nn=0; nn<BLsendDataLength; nn++)
packBuf_2[nn]=char(ui8BLsendData[nn]);
mySerialPort->writeToSerial(packBuf_2, BLsendDataLength);
} else
startFastPacking(); // quicker since 15.12.21TS
//startPacking();
}
void T_prot::startFastPacking(void)
{
uint16_t mycrc;
uint16_t sendLen;
uint8_t uctmp, nn, pp, CrcLp;
char sendBuffer[FRAME_MAXLEN], ctmp;
//qDebug() << "prot start fast packing "<<slaveAddr;
for (int nn=0; nn<FRAME_MAXLEN; nn++)
sendBuffer[nn]=0;
if (WriteCommand>9 && WriteCommand<100)
{
// long command 10...99
// WriteCommand==0 if only read request, then use short sending
sendBuffer[0]=STARTSIGN_SEND_LONG;
WrDataLength=DATALEN_SEND_LONG; // immer
//qDebug() << "send long cmd, len: " << WrDataLength;
} else
{
// fast command
sendBuffer[0]=STARTSIGN_SEND_FAST;
WrDataLength=DATALEN_SEND_FAST; // immer
//qDebug() << "send fast cmd, len: " << WrDataLength;
}
sendBuffer[1]= uint8_t(WriteCommand);
sendBuffer[2]= uint8_t(ReadCommand);
if (WriteAddr>0)
sendBuffer[3]= char(WriteAddr); // bei fast nur EINE adresse, wr hat Vorrang
else
sendBuffer[3]= char(ReadAddr);
// beim Fast prot. ist das reserve dann ists egal was drin steht
if (kindOfData) // 0: binaries, 1:text
{
for (nn=0; nn<WrDataLength; nn++)
{
pp=HEADERLEN_SEND+nn;
ctmp=(chOut_Data[nn]); // text
sendBuffer[pp]= char(ctmp);
}
} else
{
for (nn=0; nn<WrDataLength; nn++)
{
pp=HEADERLEN_SEND+nn;
uctmp=(ui8OutputData[nn]); // bin
sendBuffer[pp]= char(uctmp);
}
}
CrcLp= HEADERLEN_SEND + WrDataLength;
mycrc=0;
for (nn=0; nn<CrcLp; nn++)
{
uctmp=sendBuffer[nn];
mycrc+=uint16_t(uctmp);
//qDebug() << mycrc;
}
sendBuffer[CrcLp]=char(mycrc);
mycrc>>=8;
sendBuffer[CrcLp+1]=char(mycrc);
sendLen=CrcLp+2;
// send to VCP:
QByteArray packBuff;
packBuff.clear();
packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!!
mySerialPort->writeToSerial(packBuff, sendLen);
}
/*
void T_prot::startPacking(void)
{
uint16_t mycrc;
uint16_t uitmp, sendLen;
uint8_t uctmp, nn, pp, CrcLp;
char sendBuffer[FRAME_MAXLEN], ctmp;
//qDebug() << "prot start packing "<<slaveAddr;
for (int nn=0; nn<FRAME_MAXLEN; nn++)
sendBuffer[nn]=0;
sendBuffer[0]='>';
uitmp=slaveAddr;
sendBuffer[1]= char(uitmp);
uitmp>>=8;
sendBuffer[2]= char(uitmp);
uitmp=WriteCommand;
sendBuffer[3]= char(uitmp);
uitmp>>=8;
sendBuffer[4]= char(uitmp);
uitmp=WriteAddr;
sendBuffer[5]= char(uitmp);
uitmp>>=8;
sendBuffer[6]= char(uitmp);
uitmp=ReadCommand;
sendBuffer[7]= char(uitmp);
uitmp>>=8;
sendBuffer[8]= char(uitmp);
uitmp=ReadAddr;
sendBuffer[9]= char(uitmp);
uitmp>>=8;
sendBuffer[10]= char(uitmp);
uitmp=reserve;
sendBuffer[11]= '-'; //char(uitmp);
uitmp>>=8;
sendBuffer[12]= '-'; //char(uitmp);
sendBuffer[13]= char(WrDataLength);
CrcLp= 14 + WrDataLength;
if (kindOfData) // 0: binaries, 1:text
{
for (nn=0; nn<WrDataLength; nn++)
{
pp=14+nn;
ctmp=(chOut_Data[nn]);
sendBuffer[pp]= ctmp;
}
} else
{
for (nn=0; nn<WrDataLength; nn++)
{
pp=14+nn;
uctmp=(ui8OutputData[nn]);
sendBuffer[pp]= char(uctmp);
}
}
mycrc=0;
for (nn=0; nn<CrcLp; nn++)
{
uctmp=sendBuffer[nn];
mycrc+=uint16_t(uctmp);
//qDebug() << mycrc;
}
sendBuffer[CrcLp]=char(mycrc);
mycrc>>=8;
sendBuffer[CrcLp+1]=char(mycrc);
sendLen=CrcLp+2;
sendBuffer[CrcLp+2]=13;
sendBuffer[CrcLp+3]=10;
sendLen+=2;
// send to VCP:
QByteArray packBuff;
packBuff.clear();
packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!!
mySerialPort->writeToSerial(packBuff, sendLen);
// void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength)
}
*/
// ---------------------------------------------------------------------------------------------------------
// receiving.....
// ---------------------------------------------------------------------------------------------------------
void T_prot::analyseRecData(void)
{
// Aufruf per connect aus serialcontrol wenn Daten empfangen wurden
// getRecData(QByteArray &data, uint16_t &sendLength);
QByteArray Indata;
QString myString, tempStr;
//char recBuffer[FRAME_MAXLEN];
uint8_t recBuffer[FRAME_MAXLEN];
uint16_t recLength;
INdataValid=false;
gpi_setTxt4HsStateLine("");
gpi_setTxt4masterStateLine("");
gpi_setTxt4resultStateLine("");
gpi_setTxt4dataStateLine("");
gpi_setTxt4datifLine("");
// read from "VCP":
mySerialPort->readFromSerial(Indata, recLength);
//qDebug()<<"prot: got data " << recLength;
if (recLength>FRAME_MAXLEN)
recLength=FRAME_MAXLEN;
for (int nn=0; nn<recLength; nn++)
recBuffer[nn]=uint8_t(Indata[nn]);
myString.clear();
tempStr.clear();
//uint8_t result=FramecheckInData(recBuffer, recLength); // check input data (response from slave)
uint8_t result=FastCheckInData(recBuffer, recLength); // check input data (response from slave)
if (result>0)
{
// dann anzeige
switch (result)
{
case 1: gpi_setTxt4masterStateLine("wrong length received"); break;
case 2: gpi_setTxt4masterStateLine("wrong start sign received"); break;
case 3: gpi_setTxt4masterStateLine("received datalen too big"); break;
case 4: gpi_setTxt4masterStateLine("wrong data len received"); break;
case 5: gpi_setTxt4masterStateLine("wrong crc received"); break;
}
myString.setNum(result);
// Daten abspeichern, könnten vom BL sein:
gpi_storeRawReceivedData(uint8_t(recLength), recBuffer);
emit rawDataRecieved();
} else
{
//& result ==0
gpi_setTxt4masterStateLine("slave response OK");
// Daten OK, also prüfe Inhalt.
// Konnte der Slave das Master-Command verwenden oder hatte es Fehler?
// konnte der Slave die geforderten Daten ausgeben (DOs, AOs)?
// konnte der Slave die geforderten Daten einlesen (AIs, DIs)?
//CheckInResult(recBuffer); // Ergebnisse des Slaves anzeigen
// stimmt nicht mehr bei FastProt
ShowFastInData(recBuffer); // Eingangs-Daten des Slaves anzeigen
}
emit framerecieved();
//qDebug() << "framereceived emitted";
}
uint8_t T_prot::FastCheckInData(uint8_t *Inbuf, uint16_t LL)
{
uint16_t rawInLen=LL, crcL_Addr, recCrc, myCrc, nn, datalen, nxt;
if (Inbuf[0]!=STARTSIGN_RECEIVE_FAST && Inbuf[0]!=STARTSIGN_RECEIVE_LONG)
{
//qDebug() << "prot: got wrong start sign: " << Inbuf[0];
return 2; // wrong start sign
}
if ( (rawInLen<TELEGRAMLEN_RECEIVE_FAST && Inbuf[0]==STARTSIGN_RECEIVE_FAST) ||
(rawInLen<TELEGRAMLEN_RECEIVE_LONG && Inbuf[0]==STARTSIGN_RECEIVE_LONG) )
{
//qDebug("prot: got %d bytes only", rawInLen);
return 1; // wrong length
}
if (Inbuf[0]==0x5F)
datalen=DATALEN_RECEIVE_FAST;
else
datalen=DATALEN_RECEIVE_LONG;
crcL_Addr=datalen+HEADERLEN_RECEIVE; // weil im definierten protocol 2 bytes vor den Daten stehen
recCrc=0;
recCrc=uchar2uint(uint8_t(Inbuf[crcL_Addr+1]), uint8_t(Inbuf[crcL_Addr]));
myCrc=0;
for (nn=0; nn<crcL_Addr; nn++)
{
nxt=uint16_t (Inbuf[nn]);
nxt &=0x00FF; // the casting makes 0xFFFF out of 0xFF !!!!!!!!!
myCrc+=nxt;
//qDebug("CRC: nxt: %d sum: %d", nxt, myCrc);
}
if (myCrc != recCrc)
{
//qDebug() << "crc does not match: mycrc=" << myCrc<< " receivedCRC=" << recCrc;
//qDebug("calculated over %d bytes", crcL_Addr);
return 5; // crc wrong
}
return 0;
}
/*
uint8_t T_prot::FramecheckInData(uint8_t *Inbuf, uint16_t LL)
{
uint16_t rawInLen=LL, crcL_Addr, recCrc, myCrc, nn, datalen, nxt;
if (rawInLen<12)
{
qDebug("prot: got %d bytes only", rawInLen);
return 1; // wrong length
}
if ( Inbuf[0] != '<')
return 2; // wrong start sign
datalen=uint16_t(Inbuf[9]);
if ( datalen > FRAME_DATALEN) //[9]=reported data lenght
return 3; // reported datalen too big
if ((datalen !=(rawInLen-12)) && (datalen !=(rawInLen-13)) && (datalen !=(rawInLen-14)) )
{
// angehängtes CR und/oder LF tolerieren
qDebug() << "wrong data length, " << datalen << " " << rawInLen;
return 4; // data len does not match to complete length
}
crcL_Addr=datalen+10; // weil im definierten protocol 10 bytes vor den Daten stehen
recCrc=0;
recCrc=uchar2uint(uint8_t(Inbuf[crcL_Addr+1]), uint8_t(Inbuf[crcL_Addr]));
myCrc=0;
for (nn=0; nn<crcL_Addr; nn++)
{
nxt=uint16_t (Inbuf[nn]);
nxt &=0x00FF; // the casting makes 0xFFFF out of 0xFF !!!!!!!!!
myCrc+=nxt;
//qDebug("CRC: nxt: %d sum: %d", nxt, myCrc);
}
if (myCrc != recCrc)
{
qDebug() << "crc does not match: mycrc=" << myCrc<< " receivedCRC=" << recCrc;
qDebug("calculated over %d bytes", crcL_Addr);
return 5; // crc wrong
}
return 0;
}
*/
uint8_t T_prot::CheckInResult(uint8_t *Inbuf)
{
char slaveresult;
QString myString=nullptr, tempStr=nullptr;
// slave results anzeigen
slaveresult=Inbuf[2]; // hier steht das "Command Result" des slaves,
// d.h das Ergebnis der Protokol-Prüfung (Master->Slave)
switch (slaveresult)
{
// received message (from master) analysis:
// 0: got valid request
// this errors can only come back from a single device (not bus)
// or from a bus slave in local mode
// 1: wrong start 2: wrong length
// 3: wrong crc 4: wrong addr
case 1: gpi_setTxt4resultStateLine("slave got wrong start sign"); break;
case 2: gpi_setTxt4resultStateLine("slave got wrong length"); break;
case 3: gpi_setTxt4resultStateLine("slave got wrong crc"); break;
case 4: gpi_setTxt4resultStateLine("slave got wrong addr"); break;
case 10: gpi_setTxt4resultStateLine("slave is in local mode"); break;
case 13: gpi_setTxt4resultStateLine("local mode with wrong crc"); break;
case 14: gpi_setTxt4resultStateLine("local mode with wrong addr"); break;
// wenn 1..4 dann konnte der Slave das Mastertelegramm gar nicht verwenden, also hier Stoppen
}
if (slaveresult>0 && slaveresult<10)
return 1;
// Slave hat gültiges Kommando empfangen:
// 2.result auswerten:
// recBuffer[3]; // Write result, d.h. Ergebnis des Schreibvorganges (z.B. DOs) des Slaves
// recBuffer[4]; // Read result, d.h. Ergebnis des Lesevorganges (z.B. DIs) des Slaves
// bisher nicht bekannt welche Fehlercodes es gibt, also den code direkt ausgeben.
// bisher bekannt: 0=OK
myString.clear();
myString = "Slave OUT and IN Result: ";
tempStr.setNum(Inbuf[3],16);
myString.append(tempStr);
myString.append(" ");
tempStr.setNum(Inbuf[4],16);
myString.append(tempStr);
gpi_setTxt4resultStateLine(myString);
return 0;
}
uint8_t T_prot::ShowFastInData(uint8_t *recBuffer)
{
QString myString=nullptr, tempStr=nullptr;
uint8_t result;
RecSlaveAddr=0;
result=recBuffer[1]; // total result
result &=0x60; // only read result (bit 5,6)
if (result==0) // read result =OK,
// dann sind die Eingangsdaten gültig
{
myString.append("valid INdata: ");
INdataValid=true;
//readSource already set with sending
readAddress=0;
// RdDataLength already set with sending
if (RdDataLength>FRAME_DATALEN)
RdDataLength=FRAME_DATALEN;
for (int ii=0; ii<RdDataLength; ii++)
InputData[ii]=uint8_t(recBuffer[ii+HEADERLEN_RECEIVE]);
tempStr.setNum(readSource,16);
myString.append(tempStr);
myString.append(" add:");
tempStr.setNum(readAddress);
myString.append(tempStr);
//myString.append(" wakeSrc:");
//tempStr.setNum(lastWakeSrc);
//myString.append(tempStr);
myString.append(" Dlen:");
tempStr.setNum(RdDataLength);
myString.append(tempStr);
} else
{
myString=" "; // Eingangsdaten nicht gültig, sieht man aber weiter oben schon
}
gpi_setTxt4dataStateLine(myString);
//qDebug() << myString;
//qDebug("prot_checkInData_bindata: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ",
// InputData[0], InputData[1], InputData[2], InputData[3],
// InputData[4], InputData[5], InputData[6], InputData[7],
// InputData[8], InputData[9], InputData[10], InputData[11],
// InputData[12], InputData[13], InputData[14], InputData[15]);
return 0;
}
/*
uint8_t T_prot::ShowInData(uint8_t *recBuffer)
{
QString myString=nullptr, tempStr=nullptr;
RecSlaveAddr=recBuffer[1];
if (recBuffer[2]==0 && recBuffer[4]==0) // comand result=OK und read result =OK,
// dann sind die Eingangsdaten gültig
{
myString.append("valid INdata: ");
INdataValid=true;
readSource=uchar2uint(recBuffer[6],recBuffer[5]);
readAddress=uchar2uint(recBuffer[8],recBuffer[7]);
//lastWakeSrc=uint8_t(recBuffer[4]);
RdDataLength=uint8_t(recBuffer[9]);
if (RdDataLength>FRAME_DATALEN)
RdDataLength=FRAME_DATALEN;
for (int ii=0; ii<RdDataLength; ii++)
InputData[ii]=uint8_t(recBuffer[ii+10]);
tempStr.setNum(readSource,16);
myString.append(tempStr);
myString.append(" add:");
tempStr.setNum(readAddress);
myString.append(tempStr);
//myString.append(" wakeSrc:");
//tempStr.setNum(lastWakeSrc);
//myString.append(tempStr);
myString.append(" Dlen:");
tempStr.setNum(RdDataLength);
myString.append(tempStr);
} else
{
myString=" "; // Eingangsdaten nicht gültig, sieht man aber weiter oben schon
}
gpi_setTxt4dataStateLine(myString);
//qDebug() << myString;
//qDebug("prot_checkInData_bindata: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ",
// InputData[0], InputData[1], InputData[2], InputData[3],
// InputData[4], InputData[5], InputData[6], InputData[7],
// InputData[8], InputData[9], InputData[10], InputData[11],
// InputData[12], InputData[13], InputData[14], InputData[15]);
return 0;
}
*/
bool T_prot::ifDataReceived()
{
return INdataValid;
}
bool T_prot::getReceivedInData(uint8_t *SlavAddr, uint16_t *readSrc, uint16_t *readAddr,
uint8_t *RdDlen, uint8_t *receivedData)
{
uint8_t nn;
*SlavAddr=RecSlaveAddr;
*readSrc=readSource; // diese (Eingangs-)Daten stehen im Puffer
*readAddr=readAddress; // von dieser Adr wurden die Daten gelesen
//*lastWakSourc=lastWakeSrc; // falls der Slave den Master geweckt hat
*RdDlen=RdDataLength;
for (nn=0; nn<FRAME_DATALEN; nn++)
receivedData[nn]=0;
for (nn=0; nn<RdDataLength; nn++)
receivedData[nn]=InputData[nn];
return INdataValid; // nur true wenn CommandState OK und readState OK
}

831
src/sendWRcmd.cpp Normal file
View File

@ -0,0 +1,831 @@
#include <stdint.h>
#include <QString>
#include <QDebug>
#include "tslib.h"
#include "sendWRcmd.h"
void indat_PrnPwr(void);
void sendWRcmd_INI(void)
{
sendWRcmd_clrCmdStack();
sendWRcmd_clrCmd4Stack();
sendFDcmd_clrStack();
}
// Command Stack for commands without parameters
static uint16_t nextAsynchsendCmd0[CMDSTACKDEPTH];
static uint8_t nrOfCmdsInQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
void sendWRcmd_clrCmdStack(void)
{
uint8_t nn;
for (nn=0; nn<CMDSTACKDEPTH; nn++)
nextAsynchsendCmd0[nn]=0;
nrOfCmdsInQueue=0;
}
bool sendWRcmd_setSendCommand0(uint16_t nextCmd)
{
// write Command to memory, wait for transport
if (nrOfCmdsInQueue>=CMDSTACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd0[nrOfCmdsInQueue++]=nextCmd;
//qDebug() << "PI cmd queued:"<< nextCmd << ", saved, pp=" << nrOfCmdsInQueue;
return true; // ok, will be sent
}
uint16_t sendWRcmd_getSendCommand0(void)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmdsInQueue==0 || nrOfCmdsInQueue>CMDSTACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd0[0];
// move Puffer down by one element
if (CMDSTACKDEPTH>0)
ll=CMDSTACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
nextAsynchsendCmd0[nn]=nextAsynchsendCmd0[nn+1];
if (nrOfCmdsInQueue>0)
nrOfCmdsInQueue--;
//qDebug() << "PI cmd queued:"<< nxtAsynchCmd << ", restored, pp now =" << nrOfCmdsInQueue;
return nxtAsynchCmd;
}
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// Command Stack for commands with 4 parameters
static uint16_t nextAsynchsendCmd4[CMD4STACKDEPTH];
static uint8_t nextCmd4para1[CMD4STACKDEPTH];
static uint8_t nextCmd4para2[CMD4STACKDEPTH];
static uint8_t nextCmd4para3[CMD4STACKDEPTH];
static uint8_t nextCmd4para4[CMD4STACKDEPTH];
static uint8_t nrOfCmds4InQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
void sendWRcmd_clrCmd4Stack(void)
{
uint8_t nn;
for (nn=0; nn<CMD4STACKDEPTH; nn++)
{
nextAsynchsendCmd4[nn]=0;
nextCmd4para1[nn]=0;
nextCmd4para2[nn]=0;
nextCmd4para3[nn]=0;
nextCmd4para4[nn]=0;
}
nrOfCmds4InQueue=0;
}
bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4)
{
// write Command to memory, wait for transport
if (nrOfCmds4InQueue>=CMD4STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd4[nrOfCmds4InQueue]=nextCmd;
nextCmd4para1[nrOfCmds4InQueue]=dat1;
nextCmd4para2[nrOfCmds4InQueue]=dat2;
nextCmd4para3[nrOfCmds4InQueue]=dat3;
nextCmd4para4[nrOfCmds4InQueue]=dat4;
//qDebug() << "data with 4 data byte saved, pp=" << nrOfCmds4InQueue;
//qDebug() << " dat1=" << nextCmd4para1[nrOfCmds4InQueue] << " dat2=" << nextCmd4para2[nrOfCmds4InQueue]
// << " dat3=" << nextCmd4para3[nrOfCmds4InQueue] << " dat4=" << nextCmd4para4[nrOfCmds4InQueue];
nrOfCmds4InQueue++;
return true; // ok, will be sent
}
uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmds4InQueue==0 || nrOfCmds4InQueue>CMD4STACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd4[0];
*dat1=nextCmd4para1[0];
*dat2=nextCmd4para2[0];
*dat3=nextCmd4para3[0];
*dat4=nextCmd4para4[0];
//qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue;
//qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] <<
// " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0];
// move Puffer down by one element
if (CMD4STACKDEPTH>0)
ll=CMD4STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextAsynchsendCmd4[nn]=nextAsynchsendCmd4[nn+1];
nextCmd4para1[nn]=nextCmd4para1[nn+1];
nextCmd4para2[nn]=nextCmd4para2[nn+1];
nextCmd4para3[nn]=nextCmd4para3[nn+1];
nextCmd4para4[nn]=nextCmd4para4[nn+1];
}
if (nrOfCmds4InQueue>0)
nrOfCmds4InQueue--;
//qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue;
return nxtAsynchCmd;
}
static uint16_t nextAsynchsendCmd8[CMD8STACKDEPTH];
static uint8_t nextCmd8para1[CMD8STACKDEPTH];
static uint8_t nextCmd8para2[CMD8STACKDEPTH];
static uint16_t nextCmd8para3[CMD8STACKDEPTH];
static uint32_t nextCmd8para4[CMD8STACKDEPTH];
static uint8_t nrOfCmds8InQueue;
void sendWRcmd_clrCmd8Stack(void)
{
uint8_t nn;
for (nn=0; nn<CMD8STACKDEPTH; nn++)
{
nextAsynchsendCmd8[nn]=0;
nextCmd8para1[nn]=0;
nextCmd8para2[nn]=0;
nextCmd8para3[nn]=0;
nextCmd8para4[nn]=0;
}
nrOfCmds8InQueue=0;
}
bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4)
{
// write Command to memory, wait for transport
if (nrOfCmds8InQueue>=CMD8STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd8[nrOfCmds8InQueue]=nextCmd;
nextCmd8para1[nrOfCmds8InQueue]=dat1;
nextCmd8para2[nrOfCmds8InQueue]=dat2;
nextCmd8para3[nrOfCmds8InQueue]=dat3;
nextCmd8para4[nrOfCmds8InQueue]=dat4;
nrOfCmds8InQueue++;
return true; // ok, will be sent
}
uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmds8InQueue==0 || nrOfCmds8InQueue>CMD8STACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd8[0];
*dat1=nextCmd8para1[0];
*dat2=nextCmd8para2[0];
*dat3=nextCmd8para3[0];
*dat4=nextCmd8para4[0];
// move buffer down by one element
if (CMD8STACKDEPTH>0)
ll=CMD8STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextAsynchsendCmd8[nn]=nextAsynchsendCmd8[nn+1];
nextCmd8para1[nn]=nextCmd8para1[nn+1];
nextCmd8para2[nn]=nextCmd8para2[nn+1];
nextCmd8para3[nn]=nextCmd8para3[nn+1];
nextCmd8para4[nn]=nextCmd8para4[nn+1];
}
if (nrOfCmds8InQueue>0)
nrOfCmds8InQueue--;
return nxtAsynchCmd;
}
static uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer
static uint8_t sendAsyDatLen;
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf)
{
//qDebug() << "pi epi: storing send data";
if (leng>160) leng=160;
sendAsyDatLen=leng;
tslib_strclr(sendAsynchDataBuf, 0, 160);
for (uint8_t nn=0; nn<leng; nn++)
sendAsynchDataBuf[nn]=buf[nn];
return true; // ok, will be sent
}
uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf)
{
//qDebug() << "pi gpi: restoring send data";
*leng=sendAsyDatLen;
for (uint8_t nn=0; nn<sendAsyDatLen; nn++)
buf[nn]=sendAsynchDataBuf[nn];
sendAsyDatLen=0;
//tslib_strclr(sendAsynchDataBuf, 0, 64);
return *leng;
}
// ------------------------------------------------------------------------------------
// MDB Sendind Data are store here for next transport to DC (Device Controller)
// Transport to Slave runs every 100ms, answer from mdb-slave (e.g. coin changer) comes rigth
// with next slave answer
// start with: SENDDIRCMD_EXCHGMDB,
// send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms
static uint8_t Sdata_mdbSendBuffer[64];
static uint8_t Sdata_mdbSendLen;
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf)
{
// HWapi writes data to be forwarded to DC and further to mdb-device
for (uint8_t nn=0; nn<length; nn++)
Sdata_mdbSendBuffer[nn]=buf[nn];
Sdata_mdbSendLen=length;
return 0;
}
uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf)
{
// datif reads data to forward to dc
for (uint8_t nn=0; nn<Sdata_mdbSendLen; nn++)
buf[nn]=Sdata_mdbSendBuffer[nn];
*length=Sdata_mdbSendLen;
Sdata_mdbSendLen=0;
return 0;
}
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//---------------------------------------- Printer Text Fifo -------------------------
static uint8_t prnDataParameters[4];
static uint8_t prnDataBufferUser;
void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 )
{
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
prnDataBufferUser=user;
prnDataParameters[0]=para1;
prnDataParameters[1]=para2;
prnDataParameters[2]=para3;
prnDataParameters[3]=para4;
// qDebug() << "new user stored: " << user;
}
uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4)
{
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
//qDebug() << "returning user "<< prnDataBufferUser;
*para1=prnDataParameters[0];
*para2=prnDataParameters[1];
*para3=prnDataParameters[2];
*para4=prnDataParameters[3];
return prnDataBufferUser;
}
// Sending Text Fifo
// ONE printer doc consists of 20 x 64 byte
// #define MAXNROF_PRNBYTES 64
// #define MAXNROF_PRNBLOCKS 20
static char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES];
static uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK
//static uint8_t pPrnDataBuff; // points to next waiting printer text
// defined above, needed if more then one text is stored (before sent)
// every block will be sent after 100ms, if 8 blocks are stored within this 100ms
// then pointer goes up to 8. Important: FIFO!!!!!!!!
void epi_resetPrinterStack(void)
{
pPrnDataBuff=0;
}
uint8_t epi_storePrnText(char *buf, uint8_t leng)
{
// store text from Gui in next higher free memory 0....9
uint16_t len;
uint8_t pp, nn;
pp=pPrnDataBuff; // next free memory block with 64byte each
if (pp>=MAXNROF_PRNBLOCKS)
return 1; // not possible, no free mem
//len=tslib_strlen(buf); // kennt keine Binärzeichen!!!!!!
len=leng;
if (len>MAXNROF_PRNBYTES)
len=MAXNROF_PRNBYTES;
tslib_strclr(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES);
for (nn=0; nn<len; nn++)
Sdata_PRN_TEXT[pp][nn]=buf[nn]; // copy new text into buffer
if (pPrnDataBuff<MAXNROF_PRNBLOCKS)
pPrnDataBuff++; // inc pointer if end not yet reached
return 0; // OK
}
uint8_t gpi_restorePrnText(uint8_t *retbuf)
{
// read printer text and send to slave, size of retbuf == 64
// always read from [0] because this is the oldest (Fifo)
// then move all text lines down by one and dec pointer
uint8_t nn, pp=pPrnDataBuff;
if (pp==0) // next free memory block with 64byte each
return 1; // no text in buffer
// example: pp=5: then buffers [0...4] are occupied
for (nn=0; nn<MAXNROF_PRNBYTES; nn++)
retbuf[nn] = uint8_t (Sdata_PRN_TEXT[0][nn]); // restore oldest text
// now copy textline [1] to [0], then
// copy textline [2] to [1], then
// copy textline [3] to [2] .... upto [pp-1] to [pp-2]
// hint: copying from 9....0 would delete all strings!!!!!!
for (nn=0; nn<(pp-1); nn++)
tslib_strcpy(Sdata_PRN_TEXT[nn+1], Sdata_PRN_TEXT[nn], MAXNROF_PRNBYTES);
if (pPrnDataBuff>0)
pPrnDataBuff--;
pp=pPrnDataBuff;
// example: pp=4: then buffers [0...3] are still occupied, pp=0: all buffers empty
// now clear highest copyed line (which got free now)
tslib_strclr(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES);
// optionally: clear all remaining higher lines:
for (nn=(pp+1); nn<MAXNROF_PRNBLOCKS; nn++)
tslib_strclr(Sdata_PRN_TEXT[nn], 0, MAXNROF_PRNBYTES);
return 0;
}
uint8_t gpi_chk4remainingText(void)
{
// retval: 0: no more textline left (to send) >0: nr of 64byte-blocks
return (pPrnDataBuff);
}
// ---------------------------------------------------------------------------------
// 11.4.23 neu, Kommando direkt an "FastDevice"-protokoll senden, nicht mehr umsetzen
// ---------------------------------------------------------------------------------
// header
static uint8_t nextFDwrCmd[FDCMD_STACKDEPTH];
static uint8_t nextFDrdCmd[FDCMD_STACKDEPTH];
static uint8_t nextFDblkNr[FDCMD_STACKDEPTH];
static uint8_t nextFDshort[FDCMD_STACKDEPTH];
// short data
static uint8_t nextFDpara1[FDCMD_STACKDEPTH];
static uint8_t nextFDpara2[FDCMD_STACKDEPTH];
static uint8_t nextFDpara3[FDCMD_STACKDEPTH];
static uint8_t nextFDpara4[FDCMD_STACKDEPTH];
// lon data:
static uint8_t longFDlength[FDCMD_STACKDEPTH];
static uint8_t longFDpara[FDCMD_STACKDEPTH][64];
static uint8_t p_nextFDcmdsInQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
void sendFDcmd_clrStack(void)
{
uint8_t nn;
for (nn=0; nn<FDCMD_STACKDEPTH; nn++)
{
nextFDwrCmd[nn]=0;
nextFDrdCmd[nn]=0;
nextFDblkNr[nn]=0;
nextFDshort[nn]=0;
nextFDpara1[nn]=0;
nextFDpara2[nn]=0;
nextFDpara3[nn]=0;
nextFDpara4[nn]=0;
longFDlength[nn]=0;
memset(&longFDpara[nn][0],0,64);
}
p_nextFDcmdsInQueue=0;
}
bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4)
{
// write Command to memory, wait for transport
if (p_nextFDcmdsInQueue>=FDCMD_STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextFDwrCmd[p_nextFDcmdsInQueue]=nextWrCmd;
nextFDrdCmd[p_nextFDcmdsInQueue]=nextRdCmd;
nextFDblkNr[p_nextFDcmdsInQueue]=blockNum;
nextFDpara1[p_nextFDcmdsInQueue]=dat1;
nextFDpara2[p_nextFDcmdsInQueue]=dat2;
nextFDpara3[p_nextFDcmdsInQueue]=dat3;
nextFDpara4[p_nextFDcmdsInQueue]=dat4;
//qDebug() << "data with 4 data byte saved, pp=" << nrOfCmds4InQueue;
//qDebug() << " dat1=" << nextCmd4para1[nrOfCmds4InQueue] << " dat2=" << nextCmd4para2[nrOfCmds4InQueue]
// << " dat3=" << nextCmd4para3[nrOfCmds4InQueue] << " dat4=" << nextCmd4para4[nrOfCmds4InQueue];
nextFDshort[p_nextFDcmdsInQueue]=1; // 1=short
p_nextFDcmdsInQueue++;
/*
int nn;
if (p_nextFDcmdsInQueue==2)
{
qDebug() << "sendFDcmd_set, stack has 2 elements: " << p_nextFDcmdsInQueue;
for (nn=0; nn<16; nn++)
{
qDebug() << "header: " << nextFDwrCmd[nn] << " / " << nextFDrdCmd[nn] << " / "<< nextFDblkNr[nn] << " / " << nextFDshort[nn];
}
}
*/
/*
if (p_nextFDcmdsInQueue>15)
{
qDebug() << "sendFDcmd_set, stack is full now: " << p_nextFDcmdsInQueue;
for (nn=0; nn<16; nn++)
{
qDebug() << "header: " << nextFDwrCmd[nn] << " / " << nextFDrdCmd[nn] << " / "<< nextFDblkNr[nn] << " / " << nextFDpara1[nn] << " / " << nextFDpara2[nn] << " / " << nextFDpara3[nn] << " / " << nextFDpara4[nn];
qDebug() << " long data: " << nextFDshort[nn] << " / "<< longFDlength[nn] << " / "<< longFDpara[nn][0] << " / "<< longFDpara[nn][1]
<< " / "<< longFDpara[nn][2] << " / "<< longFDpara[nn][3] << " / "<< longFDpara[nn][4];
}
}
*/
return true; // ok, will be sent
}
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data)
{
// write Command to memory, wait for transport
// data buffer size always 64! data[64], padded with 0
uint8_t nn;
if (p_nextFDcmdsInQueue>=FDCMD_STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextFDwrCmd[p_nextFDcmdsInQueue]=nextWrCmd;
nextFDrdCmd[p_nextFDcmdsInQueue]=nextRdCmd;
nextFDblkNr[p_nextFDcmdsInQueue]=blockNum;
longFDlength[p_nextFDcmdsInQueue]=length;
for (nn=0; nn<64; nn++)
longFDpara[p_nextFDcmdsInQueue][nn]=data[nn];
nextFDshort[p_nextFDcmdsInQueue]=2;
p_nextFDcmdsInQueue++;
return true; // ok, will be sent
}
bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4)
{
uint8_t nn, ll, mm;
if (p_nextFDcmdsInQueue==0 || p_nextFDcmdsInQueue>FDCMD_STACKDEPTH)
return false; // not possible
*nextWrCmd=nextFDwrCmd[0];
*nextRdCmd=nextFDrdCmd[0];
*blockNum=nextFDblkNr[0];
*dat1=nextFDpara1[0];
*dat2=nextFDpara2[0];
*dat3=nextFDpara3[0];
*dat4=nextFDpara4[0];
//qDebug() << "sendFDcmd_get [0]; pp=" << p_nextFDcmdsInQueue;
//qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] <<
// " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0];
// move Puffer down by one element
if (FDCMD_STACKDEPTH>0)
ll=FDCMD_STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextFDwrCmd[nn]=nextFDwrCmd[nn+1];
nextFDrdCmd[nn]=nextFDrdCmd[nn+1];
nextFDblkNr[nn]=nextFDblkNr[nn+1];
nextFDpara1[nn]=nextFDpara1[nn+1];
nextFDpara2[nn]=nextFDpara2[nn+1];
nextFDpara3[nn]=nextFDpara3[nn+1];
nextFDpara4[nn]=nextFDpara4[nn+1];
nextFDshort[nn] = nextFDshort[nn+1];
longFDlength[nn] = longFDlength[nn+1];
for (mm=0; mm<64; mm++)
longFDpara[nn][mm] = longFDpara[nn+1][mm];
}
if (p_nextFDcmdsInQueue>0)
p_nextFDcmdsInQueue--;
//qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue;
// clear released buffer:
for (nn=p_nextFDcmdsInQueue; nn<FDCMD_STACKDEPTH; nn++)
{
nextFDwrCmd[nn]=0;
nextFDrdCmd[nn]=0;
nextFDblkNr[nn]=0;
nextFDpara1[nn]=0;
nextFDpara2[nn]=0;
nextFDpara3[nn]=0;
nextFDpara4[nn]=0;
nextFDshort[nn]=0;
longFDlength[nn]=0;
for (mm=0; mm<64; mm++)
longFDpara[nn][mm] = 0;
}
/*
qDebug() << "sendFDcmd_set, stack now: " << p_nextFDcmdsInQueue;
for (nn=0; nn<16; nn++)
{
qDebug() << "header: " << nextFDwrCmd[nn] << " / " << nextFDrdCmd[nn] << " / "<< nextFDblkNr[nn] << " / " << nextFDshort[nn];
qDebug() << " short data: " << nextFDpara1[nn] << " / "<< nextFDpara2[nn] << " / "<< nextFDpara3[nn]<< " / "<< nextFDpara4[nn];
qDebug() << " long data: " << longFDlength[nn] << " / "<< longFDpara[nn][0] << " / "<< longFDpara[nn][1]
<< " / "<< longFDpara[nn][2] << " / "<< longFDpara[nn][3] << " / "<< longFDpara[nn][4];
}
*/
return true; // ok, will be sent
}
uint8_t checkNextFDcmd(void)
{
// return 0: no command waiting
// 1: short cmd
// 2: long cmd
//qDebug() << "chk nxt fd cmd: "<<p_nextFDcmdsInQueue<<" "<<nextFDshort[0]<<" "<<nextFDshort[1]<<" "<<nextFDshort[2]<<" "<<nextFDshort[3];
if (p_nextFDcmdsInQueue==0)
return 0;
if (nextFDshort[0]==1)
return 1;
return 2;
}
uint8_t check4FDshortCmd(void)
{
// returns number of waiting command, max FDCMD_STACKDEPTH
return p_nextFDcmdsInQueue;
}
uint8_t check4freeFDshortCmd(void)
{
// returns number of free places in short-command stack
return FDCMD_STACKDEPTH - p_nextFDcmdsInQueue;
}
// long command, 64 data bytes
//static uint8_t longFDwrCmd[FDLONG_STACKDEPTH];
//static uint8_t longFDrdCmd[FDLONG_STACKDEPTH];
//static uint8_t longFDblkNr[FDLONG_STACKDEPTH];
//static uint8_t longFDlength[FDLONG_STACKDEPTH];
//static uint8_t longFDpara[FDLONG_STACKDEPTH][64];
//static uint8_t p_longFDcmdsInQueue;
/*
void longFDcmd_clrStack(void)
{
uint8_t nn, mm;
for (nn=0; nn<FDLONG_STACKDEPTH; nn++)
{
longFDwrCmd[nn]=0;
longFDrdCmd[nn]=0;
longFDblkNr[nn]=0;
longFDlength[nn]=0;
for (mm=0; mm<64; mm++)
longFDpara[nn][mm]=0;
}
p_longFDcmdsInQueue=0;
}*/
bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data)
{
uint8_t nn, mm, ll;
//p_nextFDcmdsInQueue; nn<FDCMD_STACKDEPTH
if (p_nextFDcmdsInQueue==0 || p_nextFDcmdsInQueue>FDCMD_STACKDEPTH)
return false; // not possible
*nextWrCmd=nextFDwrCmd[0];
*nextRdCmd=nextFDrdCmd[0];
*blockNum=nextFDblkNr[0];
*length = longFDlength[0];
for (mm=0; mm<64; mm++)
data[mm] = longFDpara[0][mm];
// move Puffer down by one element
if (FDCMD_STACKDEPTH>0)
ll=FDCMD_STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextFDwrCmd[nn]=nextFDwrCmd[nn+1];
nextFDrdCmd[nn]=nextFDrdCmd[nn+1];
nextFDblkNr[nn]=nextFDblkNr[nn+1];
nextFDpara1[nn]=nextFDpara1[nn+1];
nextFDpara2[nn]=nextFDpara2[nn+1];
nextFDpara3[nn]=nextFDpara3[nn+1];
nextFDpara4[nn]=nextFDpara4[nn+1];
nextFDshort[nn] = nextFDshort[nn+1];
longFDlength[nn] = longFDlength[nn+1];
for (mm=0; mm<64; mm++)
longFDpara[nn][mm] = longFDpara[nn+1][mm];
}
if (p_nextFDcmdsInQueue>0)
p_nextFDcmdsInQueue--;
// clear released buffer:
for (nn=p_nextFDcmdsInQueue; nn<FDCMD_STACKDEPTH; nn++)
{
nextFDwrCmd[nn]=0;
nextFDrdCmd[nn]=0;
nextFDblkNr[nn]=0;
nextFDpara1[nn]=0;
nextFDpara2[nn]=0;
nextFDpara3[nn]=0;
nextFDpara4[nn]=0;
nextFDshort[nn]=0;
longFDlength[nn]=0;
for (mm=0; mm<64; mm++)
longFDpara[nn][mm] = 0;
}
return true; // ok, will be sent
}
/*
uint8_t check4FDlongCmd(void)
{
// returns number of waiting command
return p_longFDcmdsInQueue;
}
uint8_t check4freeFDlongCmd(void)
{
// returns number of free places in command stack
return FDLONG_STACKDEPTH - p_longFDcmdsInQueue;
}
*/
static uint8_t Sdata_DeviceParameter[64];
static uint8_t Sdata_DevParaLen;
uint8_t epi_store64BdevParameter(uint8_t length, uint8_t *buf)
{
// HWapi writes data to be stored
uint8_t nn;
for (nn=0; nn<length; nn++)
Sdata_DeviceParameter[nn]=buf[nn];
for (nn=length; nn<64; nn++)
Sdata_DeviceParameter[nn]=0;
Sdata_DevParaLen=length;
return 0;
}
uint8_t epi_restore64BdevParameter(uint8_t *length, uint8_t *buf)
{
for (uint8_t nn=0; nn<Sdata_DevParaLen; nn++)
buf[nn]=Sdata_DeviceParameter[nn];
*length=Sdata_DevParaLen;
return 0;
}

46
src/shared_mem_buffer.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "shared_mem_buffer.h"
#include <QDebug>
#include <atomic>
#ifdef QT_POSIX_IPC
// The POSIX backend can be explicitly selected using the -feature-ipc_posix
// option to the Qt configure script. If it is enabled, the QT_POSIX_IPC
// macro will be defined. -> we use SystemV shared memory
#error "QT_POSIX_IPC defined"
#else
#ifdef __linux__
#include <sys/ipc.h> // ftok
#endif
#endif
// std::atomic_bool SharedMemBuffer::__sharedMemLocked{false};
QSharedMemory *SharedMemBuffer::getShm(std::size_t size) {
static QSharedMemory shMem;
if (size > 0) {
#ifdef __linux__
static const long nativeKey = ftok("/etc/os-release", 'H');
static const QString fkey = std::to_string(nativeKey).c_str();
#else
static const QString fkey = "0123456?000=9";
#endif
shMem.setKey(fkey);
if (!shMem.isAttached()) {
if (shMem.create(size)) {
return &shMem;
} else {
if (shMem.error() == QSharedMemory::AlreadyExists) {
if (shMem.attach()) {
return &shMem;
}
}
}
qCritical() << shMem.nativeKey() << shMem.key() << shMem.data()
<< shMem.error() << shMem.errorString();
return nullptr;
}
}
return &shMem;
}

1939
src/storeINdata.cpp Normal file

File diff suppressed because it is too large Load Diff

598
src/tslib.cpp Normal file
View File

@ -0,0 +1,598 @@
#include "tslib.h"
#include <QThread>
//tslib::tslib()
//{
//}
/*
uint16_t tslib::uchar2uint(uint8_t Highbyte, uint8_t Lowbyte)
{
uint16_t uitmp;
uitmp=0;
uitmp |= uint8_t(Highbyte);
uitmp<<=8;
uitmp |= uint8_t(Lowbyte);
return uitmp;
}
uint8_t tslib::uint2uchar(uint16_t uival, bool getHighB)
{
// getHighB: low=GetLowByte
uint16_t uitmp=uival;
if (getHighB==0)
return uint8_t(uitmp);
uitmp>>=8;
return uint8_t(uitmp);
}*/
uint16_t uchar2uint(char Highbyte, char Lowbyte)
{
uint16_t uitmp;
uitmp=0;
uitmp |= uint8_t(Highbyte);
uitmp<<=8;
uitmp |= uint8_t(Lowbyte);
return uitmp;
}
uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte)
{
uint16_t uitmp;
uitmp=0;
uitmp |= uint8_t(Highbyte);
uitmp<<=8;
uitmp |= uint8_t(Lowbyte);
return uitmp;
}
uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte)
{
uint32_t ultmp=0;
ultmp |= uint8_t(Highbyte);
ultmp<<=8;
ultmp |= uint8_t(MHbyte);
ultmp<<=8;
ultmp |= uint8_t(MLbyte);
ultmp<<=8;
ultmp |= uint8_t(Lowbyte);
return ultmp;
}
uint8_t uint2uchar(uint16_t uival, bool getHighB)
{
// getHighB: low=GetLowByte
uint16_t uitmp=uival;
if (getHighB==0)
return uint8_t(uitmp);
uitmp>>=8;
return uint8_t(uitmp);
}
uint8_t ulong2uchar(uint32_t ulval, uint8_t getBytNr)
{
// getBytNr: 0=LSB 3=MSB
uint32_t ultmp=ulval;
if (getBytNr==0)
return uint8_t(ultmp);
ultmp>>=8;
if (getBytNr==1)
return uint8_t(ultmp);
ultmp>>=8;
if (getBytNr==2)
return uint8_t(ultmp);
ultmp>>=8;
return uint8_t(ultmp);
}
void delay(uint16_t MilliSec)
{
QThread::msleep(uint32_t(MilliSec));
}
void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf)
{
// Zahlenwerte in String wandeln, 12/24h-Format // 12byte für buf!
uint8_t usa;
uint16_t jj;
uint8_t hh, mm, ss, with_sec;
// buf[0]= ganz linkes Zeichen
hh=hours;
mm=minutes;
ss=seconds;
// 15.10.12, Plausibilitätsprüfung --------------------------------------------------
if (hh>23) hh=0;
if (mm>59) mm=0;
if (ss>59) ss=0;
with_sec=ShowSec;
for (jj=0; jj<12; jj++) buf[jj]=0;
usa = System12h; // 1:12h 0:24h
// Stunden:
if (usa)
{
// 12h System
if (hh==0 || hh==12)
{
// 12AM (Mitternacht) oder 12PM (Mittag)
buf[0]=0x31;
buf[1]=0x32;
} else
if (hh<12)
{
// 1..11AM
buf[0]=hh/10+0x30;
buf[1]=hh%10+0x30;
} else
{
//13:00 bis 23Uhr
buf[0]=(hh-12)/10+0x30;
buf[1]=(hh-12)%10+0x30;
}
} else
{
// 24h System
buf[0]=hh/10+0x30;
buf[1]=hh%10+0x30;
}
// Minuten:
buf[2]=':';
buf[3]=mm/10+0x30;
buf[4]=mm%10+0x30;
jj=5;
if (with_sec)
{
buf[jj++]=':';
buf[jj++]=ss/10+0x30;
buf[jj++]=ss%10+0x30;
}
if (usa)
{
buf[jj++]=' ';
if (hh<12)
buf[jj++]='A';
else
buf[jj++]='P';
buf[jj++]='M';
}
}
// ------------------- ********************************************************************************
void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf)
{
// generate date as ascii string from integers day/month/year
// yearhigh: 10..29, in europe always 20 (not in arabia!) comes as hex number, e.g. 0x20
// format= 0: dd.mm.yyyy (deutsch)
// 1: mm.dd.yyyy (amerika)
// 2: yyyy.mm.dd (Iran, Dubai)
// 3: dd.yyyy.mm
// 4: mm.yyyy.dd
// 5: yyyy.dd.mm
// sep: 0: use . as seperator 1: use / as seperator
// return String in *buf // 11byte für buf!
uint8_t tag, mon, jahr, d10, d1, m10, m1, y1000, y100, y10, y1;
uint8_t slash;
y100= (yearhigh & 0x0F)+0x30;
y1000=((yearhigh & 0xF0)>>4)+0x30;
// if (yearhigh>=20)
// {
// y1000='2';
// y100=28+yearhigh; // '0' + (yearhigh-20)
// } else
// if (yearhigh<20)
// {
// y1000='1';
// y100=38-yearhigh; // '9' - (19-yearhigh)
// }
tag=day;
mon=month;
jahr=yearlow;
if (mon>12 || mon==0) mon=1; // 23.10.12
if (tag>31 || tag==0) tag=1;
if (jahr>50 || jahr<11) jahr=1;
if (sep==0)
slash='.'; // slash==0
else if (sep==1)
slash='/';
else
if (sep>=0x20)
slash=sep;
else
slash='.';
d10 =tag/10;
d1 =tag%10;
m10 =mon/10;
m1 =mon%10;
y10 =jahr/10;
y1 =jahr%10;
d10 +=0x30; // in Asccii wandeln
d1 +=0x30;
m10 +=0x30;
m1 +=0x30;
y10 +=0x30;
y1 +=0x30;
switch (format)
{
// 0: dd.mm.yyyy
case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash;
buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break;
// 1: mm.dd.yyyy
case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash;
buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break;
// 2: yyyy.mm.dd
case 2: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=m10;
buf[6]=m1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break;
// 3: dd.yyyy.mm
case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=y1000; buf[4]=y100;
buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break;
// 4: mm.yyyy.dd
case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=y1000; buf[4]=y100;
buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break;
// 5: yyyy.dd.mm
case 5: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=d10;
buf[6]=d1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break;
}
buf[10]=0;
}
// ------------------- ********************************************************************************
void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf)
{
// generate date as ascii string from integers day/month/year
// format= 0: dd.mm.yy (deutsch)
// 1: mm.dd.yy (amerika)
// 2: yy.mm.dd (Iran, Dubai)
// 3: dd.yy.mm
// 4: mm.yy.dd
// 5: yy.dd.mm
// sep: 0: use . as seperator 1: use / as seperator
// return String in *buf // 11byte für buf!
uint8_t tag, mon, jahr, d10, d1, m10, m1, y10, y1;
uint8_t slash;
tag=day;
mon=month;
jahr=yearlow;
if (mon>12 || mon==0) mon=1; // 23.10.12
if (tag>31 || tag==0) tag=1;
if (jahr>50 || jahr<11) jahr=1;
if (sep==0)
slash='.'; // slash==0
else if (sep==1)
slash='/';
else if (sep>=0x20)
slash=sep;
else
slash='.';
d10 =tag/10;
d1 =tag%10;
m10 =mon/10;
m1 =mon%10;
y10 =jahr/10;
y1 =jahr%10;
d10 +=0x30; // in Asccii wandeln
d1 +=0x30;
m10 +=0x30;
m1 +=0x30;
y10 +=0x30;
y1 +=0x30;
switch (format)
{
// 0: dd.mm.yyyy
case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash;
buf[6]=y10; buf[7]=y1; break;
// 1: mm.dd.yyyy
case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash;
buf[6]=y10; buf[7]=y1; break;
// 2: yyyy.mm.dd
case 2: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=m10;
buf[4]=m1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break;
// 3: dd.yyyy.mm
case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash;
buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break;
// 4: mm.yyyy.dd
case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash;
buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break;
// 5: yyyy.dd.mm
case 5: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=d10;
buf[4]=d1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break;
}
buf[8]=0;
}
uint16_t tslib_strlen(char *buf)
{
uint16_t nn;
for (nn=0; nn<0xFFF0; nn++)
if (buf[nn]==0)
return nn;
return 0;
}
uint16_t tslib_strlen(uint8_t *buf)
{
uint16_t nn;
for (nn=0; nn<0xFFF0; nn++)
if (buf[nn]==0)
return nn;
return 0;
}
void tslib_strclr(char *buf, char clrsign, uint16_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
buf[nn]=clrsign;
}
void tslib_strclr(uint8_t *buf, char clrsign, uint16_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
buf[nn]=uint8_t (clrsign);
}
void tslib_strcpy(char *srcbuf, char *destbuf, uint16_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
destbuf[nn]=srcbuf[nn];
}
void tslib_strcpy(char *srcbuf, uint8_t *destbuf, uint16_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
destbuf[nn]=uint8_t(srcbuf[nn]);
}
void tslib_strcpy(uint8_t *srcbuf, uint8_t *destbuf, uint16_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
destbuf[nn]=srcbuf[nn];
}
bool tslib_isDecAsciiNumber(char sign)
{
if (sign>=0x30 && sign<=0x39)
return true;
return false;
}
bool tslib_isHexAsciiNumber(char sign)
{
if (sign>=0x30 && sign<=0x39)
return true;
if (sign>=0x61 && sign<=0x66) // a...f
return true;
if (sign>=0x41 && sign<=0x46) // A...F
return true;
return false;
}
int tslib_getMinimum(int val1, int val2)
{
if (val1<val2)
return val1;
return val2;
}
void tslib_text2array(QByteArray text, char *aray, uint16_t maxArayLen)
{
QByteArray sloc;
int ii, LL=text.length();
if (LL>maxArayLen) LL=maxArayLen;
for (ii=0; ii<LL; ii++)
{
aray[ii]=text.at(ii);
}
if (LL==maxArayLen)
aray[LL-1]=0;
else
aray[LL]=0;
}
// -----------------------------------------------------------------------------------------------
// functions for DeviceController's Bootloader ---------------------------------------------------
// -----------------------------------------------------------------------------------------------
/*
uint16_t tslib_calcCrcCcitt(uint16_t BufLength, uint8_t *buf)
{
uint8_t nn, B15H, element;
uint16_t crc = 0x84cf;
while (BufLength--)
{
element = *buf++;
for (nn = 0; nn < 8; nn++)
{
B15H = 0;
if(crc & 0x8000)
B15H = 1;
crc = (crc << 1) | ((element >> (7 - nn)) & 0x01);
if (B15H)
{
crc ^= 0x1021;
}
}
}
for (nn = 0; nn < 16; nn++)
{
B15H = 0;
if(crc & 0x8000)
B15H = 1;
crc = (crc << 1) | 0x00;
if (B15H)
{
crc ^= 0x1021;
}
}
return crc;
}
static uint8_t LastBLcmd; // stored the last sent cmd in order to analys response
// cmd echo'ed: error cmd or'ed with 0x80: OK
uint8_t tslib_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf)
{
// make BL protocol, retval = outbuf length (5...133)
// bring data in correct form: start always with 0x02 finish with 0x03 and append checksum
// 0x02 Cmd < ...sendData ..> CRC CRC 0x03
// Data length = 0...64
// special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80
// so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64
uint8_t myBuf[140], pp=0, nn, uctmp, currLen=0;
uint16_t calcCrc;
tslib_strclr(myBuf, 0, 140);
myBuf[pp++]=2; // STX
myBuf[pp++]=Cmd;
LastBLcmd=Cmd;
// append data:
for (nn=0; nn<SendDataLength; nn++)
{
uctmp=sendData[nn];
if (uctmp==2 || uctmp==3) // STX or ETX in normal data!
{
myBuf[pp++]=0x1B; // ESC
myBuf[pp++]=uctmp | 0x80;
} else
myBuf[pp++]=uctmp;
}
currLen=pp;
// calc crc: (over cmd and data, without STX)
calcCrc=tslib_calcCrcCcitt(uint16_t(currLen), myBuf);
myBuf[pp++]=uint8_t(calcCrc & 0x00FF);
myBuf[pp++]=uint8_t((calcCrc>>8) & 0x00FF);
myBuf[pp++]=3;
currLen=pp;
return currLen;
}
// some special commands (right out of bootloader manual)
uint8_t tslib_readBLversion(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
tslib_strclr(myBuf, 0, 2);
return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData);
}
uint8_t tslib_readFWversion(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
tslib_strclr(myBuf, 0, 2);
return tslib_prepareDC_BLcmd(0x12, 0, myBuf, sendData);
}
uint8_t tslib_exitBL(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
tslib_strclr(myBuf, 0, 2);
return tslib_prepareDC_BLcmd(0x18, 0, myBuf, sendData);
}
uint8_t tslib_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData)
{
// minimum size of sendData-buffer: 13byte retval: length (9...13)
uint8_t myBuf[2];
tslib_strclr(myBuf, 0, 2);
return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData);
}
*/
// -----------------------------------------------------------------------------------------------
void biox_CopyBlock(uint8_t *src, uint16_t srcPos, uint8_t *dest, uint16_t destPos, uint16_t len)
{
// both buffers starting from pos 0
uint16_t xx,yy,zz,ii;
xx = srcPos;
yy = destPos;
zz = len;
for (ii = 0; ii < zz; ++ii)
{
dest[yy + ii] = src[xx + ii];
}
}