diff --git a/DCPlugin/include/hwapi.h b/DCPlugin/include/hwapi.h
index 287dc69..03b6135 100644
--- a/DCPlugin/include/hwapi.h
+++ b/DCPlugin/include/hwapi.h
@@ -1,1249 +1,1249 @@
-/*
-matching interfaces.h:
-
-// History
-// 11.10.2021: V1.0  222 functions
-// 23.12.2021: V1.1  added block-parameter to function "read mifare data"
-// 30.12.2021: V1.2  added function: mif_clearDataBuffer(), mif_isBlockAvailable(uint8_t blkNr) and mif_getAvailableDataBlocks()
-// 1.1.2022: V1.3    Mifare extended. ( background: read 16 x 48byte from card to DC, read 12 x 64byte from DC to CA)
-//                   new:  read full card with 768bytes from HWapi without block borders
-//                   added: mif_getNrOfAvailableDataBytes     mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize)
-//                           mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize)
-//                            mif_getCardDataStr(bool useHexFormat, char seperator)
-// 29.03.2023: V3.1 some extensions for PSA1256_ptu5,
-//             V3.2 Bootloader improvement
-// 12.04.2023: V3.3 new features extended: loading and using Json-files, cash-collection, cash-data-logging
-
-//#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1"
-//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.1"
-#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.3"
-
-
-PSA1259 hardware control using the DeviceController DC2
-
-covering enclosure (switches and doors) and money devices,
-controls mifare card to access or program
-optional it can control printer, modem, bar code reader and credit card
-
- * API to the PSA1259 Hardware
- * All data come in from device controller via serial interface and will be stored
- * in "PI" = peripheral image
- * PI is updated every 100ms (up to 30ms possible)
- * This api uses stored pi data and returns them in the following functions
- * created: Q1/2020 TS
- *
-
-The devices, connected to device controller2 (DC2) can be controlled in different access levels.
-Level 1:
-    direct connection to DC2, check versions, state and parameters
-    control serial interfaces
-    digital/analog IO's
-    read and write to connected devices on lowest level, this is a kind of fall-back-level
-    in case higher levels fail or do not support the needed (new) function
-    Example: send a specific printer command, several bytes that need to be conform to
-            printer manual. This command is routed to the printer through the DC2 without
-            any action of the DC. You can write your own device driver that way.
-    Level 1 is flexible but complicated
-
-Level 2:
-   The DC controls the connected devices containing a device driver. The DC offers
-   usage of the device by simple commands,
-   Example: "Printer on", "set Font size 3" "print "hello world"", "cut"
-   In opposite to level 1 where you had to send a set of numbers and letters.
-   In other words: you "talk" to the device controller, not to the device itself.
-
-Level 3:
-    start/stop complete processes.
-    Example: 1) print (predefined) document nr 3 with Text, letter size, font set, cut.
-                Also power up/down the printer, check if paper ok and so on.
-*/
-
-/*
-Another access example: control the coin unit
-
-Level 1): read digital inputs to detect coin,
-          switch digital output which opens coin slot
-          communicate with coin checker by certain mdb-commands (manual conform)
-          poll coin checker for inserted coins
-          close coin slot after 3seconds by setting DO to 0....
-
-Level 2): get message of attached coin from DC
-          send command "initialize coin checker" to DC
-          send command "open slot for 3s"
-          poll DC for inserted coins, DC polls coin checker in right way, no need
-                to know the data sheet of the coin checker or mdb-bus
-          command to DC "open coin escrow's return flap for 1s"
-
-Level 3): send command: "start payment process"
-          all coin devices are started up
-          coin blocker opens for 3s if a coin is attached
-          coin checker summarizes inserted value and reports sum
-          later send command "stop payment process" (puts coins to vault) or
-          send command "cancel payment process" (returns coins to user)
-
-*/
-
-#ifndef hwapi_H
-#define hwapi_H
-
-#include <stdint.h>
-#include <QTabWidget>
-#include <QtPlugin>
-#include <QObject>
-#include "interfaces.h"
-#include "datIf.h"
-
-
-
-class hwapi :   public QObject,
-                public hwinf
-{
-    Q_OBJECT
-    Q_PLUGIN_METADATA(IID "Atb.Psa2020.software.HWapi/1.0" )   //FILE "HWapi.json")
-    Q_INTERFACES(hwinf)
-
-    DownloadResult sendNextAddress(int bNum) const;
-    DownloadResult sendNextDataBlock(QByteArray const &b, int bNum) const;
-    DownloadResult sendStatus(int ret) const;
-    DownloadResult dc_downloadBinary(QByteArray const &binary) const;
-
-    bool startBootloader() const;
-    bool stopBootloader() const;
-    bool openSerial(int br, QString baudrate, QString comPort) const;
-    bool closeSerial(QString comport) const;
-    bool resetDeviceController() const;
-    QByteArray loadBinaryDCFile(QString filename) const;
-    bool downloadBinaryToDC(QString const &bFile) const;
-public:
-    explicit hwapi(QWidget *parent = nullptr);
-
-    T_datif *myDatif;
-
-
-    // ------------------------------------------------------------------------------
-    // Level 0 commands, interface
-    // open, close, change serial interface
-    // actually not neccessary as it is opened automatically on program start
-    // start automatic READ requests
-    // ------------------------------------------------------------------------------
-
-    bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const override;
-        // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
-        // BaudStr: for exapmle "19200"
-        // ComName: for example "COM48"
-        // connect: 0, 1
-
-    bool dc_closeSerial(void) const override;
-
-    bool dc_isPortOpen(void) const override ;
-
-    void dc_autoRequest(bool on) const override ;
-        // select if READ-Requests are sent manually one by one or automatically
-        // automatically request ALL digital and analog sensors, get time/date, get status information
-
-    bool dc_updateDC(QString binFileName, QString baudrate,
-                     QString comPort) const override;
-    
-    bool dc_updatePrinterTemplate(enum FileTypeJson type,
-                                  QVector<int> templateIdx,
-                                  QVector<QString> fnames,
-                                  QString br,
-                                  QString serial) const override;
-
-    bool dc_printTemplate(enum FileTypeJson type,
-                          QVector<int> templateIdx,
-                          QString br,
-                          QString serial) const override;
-    // ------------------------------------------------------------------------------
-    // Level 1, control device-controller (functions of µC)
-    // check serial connection to deviceController
-    // read response from DC2 (input data)
-    // some test function for serial communication
-    // also Bootloader is here
-    // ------------------------------------------------------------------------------
-
-    void dc_requTestResponse() const override;
-        // tell DC2 to return his TestString in order
-        //   to test the serial and the baudrate
-        // must always be triggered manually, is never sent automatically
-
-    bool dc_readAnswTestResponse() const override;
-        // retval: true: test was successful, got right response
-
-    uint8_t dc_isRequestDone(void) const override;
-        // retval:  0: request is still in progress
-        //          1: answer from DC2 was OK
-        //          2: wrong answer from DC2
-
-    uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const override;
-        // get data back in *pl, max 64 byte, can be used for diagnosis
-        // 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
-
-    void dc_setWakeFrequency(uint8_t period) const override;
-        // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
-        // change wake signal period to 1...64s
-
-    void dc_OrderToReset(void) const override;
-        // want DC2 to reset (in order to start Bootloader)
-
-    QString dc_getSerialState(void) const override;
-    void dc_clrSerialStateText(void) const override;
-
-    void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const override;
-        // send without protocol frame, needed for the DC bootloader
-
-    uint8_t getRawRecLength(void) const override;
-
-    uint8_t getRawReceivedData(uint8_t *receivedData) const override;
-
-    QString dc_getSerialParams(void) const override;
-
-    QString dc_getHWversion(void) const override;
-
-    QString dc_getSWversion(void) const override;
-
-    QString dc_getState(void) const override;
-
-    QString dc_getTxt4RsDiagWin(void) const override;
-    void dc_clrTxt4RsDiagWin(void) const override;
-    QString dc_get2ndTxt4RsDiagWin(void) const override;
-    void dc_clr2ndTxt4RsDiagWin(void) const override;
-    QString dc_getTxt4HsStateLine(void) const override;
-    void dc_clrTxt4HsStateLine(void) const override;
-    QString dc_getTxt4masterStateLine(void) const override;
-    void dc_clrTxt4masterStateLine(void) const override;
-    QString dc_getTxt4resultStateLine(void) const override;
-    void dc_clrTxt4resultStateLine(void) const override;
-    QString dc_getdataStateLine(void) const override;
-    void dc_clrTxt4dataStateLine(void) const override;
-    QString dc_getdatifLine(void) const override;
-    void dc_clrTxt4datifLine(void) const override;
-
-    // using DC2 Bootloader
-    void bl_iniChain(void) const override;
-    bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const override;
-    uint8_t bl_activatBootloader(uint8_t *sendData) const override;
-    uint8_t bl_startChain(void) const override;
-    uint8_t bl_readBLversion(uint8_t *sendData) const override;
-        // minimum size of sendData-buffer: 5byte  retval: length
-    uint8_t bl_readFWversion(uint8_t *sendData) const override;
-        // minimum size of sendData-buffer: 5byte  retval: length
-
-    uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const override;
-        // 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 bl_exitBL(uint8_t *sendData) const override;
-        // minimum size of sendData-buffer: 5byte  retval: length
-
-    // ------------------------------------------------------------------------------
-    // Level 2  DC2-onboard devices
-    //          WR: set time
-    //          RD. get time, get measure, get test results
-    // ------------------------------------------------------------------------------
-
-    // get UID, get time/date   test results   memory,  RTC  analog values
-/*
-    struct Trtc_DateTime
-    {
-        uint8_t rtc_hour;
-        uint8_t rtc_min;
-        uint8_t rtc_sec;
-        uint8_t rtc_dayOfMonth;
-        uint8_t rtc_month;
-        uint8_t rtc_year;
-        uint8_t rtc_dayOfWeek;
-    };
-*/
-    uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const override;
-
-    uint8_t rtc_setDateTime(void) const override;
-        // synch DC2 with PC or PTU system time and date
-
-    void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const override;
-        // get time directly
-
-    void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const override;
-        // get date directly
-
-    uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const override;
-        // dow=day of week, 1=monday...7
-        // minOfToday: 0=midnight...1439= 23:59
-        // secOfToday: 0=midnight...86399= 23:59:59
-
-    bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const override;
-        // retval true: this year is leap year
-
-    bool rtc_isLeapYear() const override;
-
-    void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const override;
-        // DayOfWeek: 1=monday...7
-        // HoursOfWeek: 0=Monday 0:00 o'clock...167=Sunday 23:00
-        // MinutesOfWeek: 0=Monday 0:00 o'clock...10079=Sunday 23:59
-
-    void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const override;
-        // DayOfMonth: 1...31
-        // HoursOfMonth: 0 = 0:00o'clock of 1.day in month     up to 743
-        // MinutesOfMonth:0 = 0:00o'clock of 1.day in month     up to 44639
-
-    void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const override;
-        // DayOfYear: 1...366  1= 1.Jan of this current year
-        // HoursOfYear: 0=1.Jan 0:00o'clock ...8783=31.12 23 o'clock
-        // MinutesOfYear: 0=1.Jan 0:00o'clock ...527039=31.12 23:59 o'clock
-
-    QString rtc_getTimStr(void) const override;
-    QString rtc_getDatStr(void) const override;
-    QString rtc_getTimDatStr(void) const override;
-
-    // UID
-    void     dc_getUID8byte(uint8_t *buf8byteUid) const override;
-    QString  dc_getUIDstr() const override;
-    uint64_t dc_getUIDnumber(void) const override;
-
-
-    // Analog inputs:
-    uint32_t dc_getTemperature(void) const override;       // in Sax-Format 0...400 (0=-50,0°C    100=0,0°C    141=20,5°C    400=150,0°C)
-    QString  dc_getTemperaturStr(void) const override;
-
-    uint32_t dc_getVoltage(void) const override;           // in mV,  0...65,535V
-    QString  dc_getVoltagStr(void) const override;
-
-    bool dc_mainFuseIsOk(void) const override;
-
-    // ------------------------------------------------------------------------------
-    // Level 3: digital outputs and simple switching of connected devices
-    //          simple processes like flashing a led or open flap for 1s
-    // ------------------------------------------------------------------------------
-
-    void lock_switchContactPower(bool on) const override;
-
-    // Locks move until stop cmd (0)
-    uint8_t lock_switchUpperLock(uint8_t dir) const override;
-        // dir 0=off 1=up 2=down
-    uint8_t lock_switchLowerLock(uint8_t dir) const override;
-        // dir 0=off 1=up 2=down
-    void lock_switchVaultDoor(void) const override;
-
-    void coin_switchRejectMotor(uint8_t dir) const override;
-
-    void coin_rejectCoins(void) const override;
-
-    // LEDs
-    void led_switchLedIllumination(uint8_t on) const override;
-    void led_switchLedService(uint8_t on) const override;
-    void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const override;
-    void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const override;
-    void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const override;
-    void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const override;
-
-    void fan_switchFan(bool on) const override;
-    void alarm_switchSiren(bool on) const override;
-    void bar_OpenBarrier(bool open) const override;
-    void ptu_switchWake(bool WAKEACTIVE) const override;
-
-    void prn_switchPower(bool on) const override;
-
-    void mif_readerOn(bool on) const override;
-    void shut_move(bool open) const override;
-    void esc_moveFlaps(uint8_t flap ) const override;
-        // 0: close both  1: open take-flap   2: open return
-
-    void mdb_switchPower(bool on) const override;
-    void mdb_switchWake(bool WAKEACTIVE) const override;
-
-    void mod_switchPower(bool on) const override;
-    void credit_switchPower(bool on) const override;
-
-    void aux_power(bool on) const override;
-    void aux_setUsage(uint8_t PinDirection) const override;
-    void aux_setOutputs(uint8_t PinIsHigh) const override;
-
-
-    void mod_switchWake(bool WAKEACTIVE) const override;
-
-    void credit_switchWake(bool WAKEACTIVE) const override;
-
-
-
-
-    // ------------------------------------------------------------------------------
-    // Level 3: digital inputs of connected devices
-    // ------------------------------------------------------------------------------
-
-    bool door_isContactPowerOn(void) const override;
-
-    uint8_t door_getSwitches(void) const override;
-        // retval:  bit0: upper door  1: low door  2:vault door
-
-    bool    door_isUpperDoorOpen(void) const override;
-
-    bool    door_isLowerDoorOpen(void) const override;
-
-    bool    vault_isVaultDoorOpen(void) const override;
-
-    uint8_t vault_getSwitches(void) const override;
-        // retval bit0: cash box,  bit 1: bill box
-
-    bool    vault_isCoinVaultIn(void) const override;
-
-    bool    vault_isBillVaultIn(void) const override;
-
-    uint8_t door_getLocks(void) const override;
-        // retval bit0: upper lever is up
-        //        bit1: upper lever is down
-        //        bit2: lower lever is up
-        //        bit3: lower lever is down
-
-    bool door_upperDoorIsLocked(void) const override;
-
-    bool door_upperDoorIsUnlocked(void) const override;
-
-    bool door_lowerDoorIsLocked(void) const override;
-
-    bool door_lowerDoorIsUnlocked(void) const override;
-
-    bool bar_optoIn1isOn(void) const override;
-
-    bool bar_optoIn2isOn(void) const override;
-
-    bool ptu_WakeINisActive(void) const override;
-
-    bool prn_isPrinterPowerOn(void) const override;
-    uint8_t prn_PrnFuseIsOk(void) const override;
-    //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off
-
-    bool prn_readyINisActive(void) const override;
-
-    bool mif_cardIsAttached(void) const override;
-    bool mif_isMifarePowerOn(void) const override;
-
-    bool mdb_WakeINisActive(void) const override;
-    bool mdb_testIsmdbTxDon(void) const override;
-    bool mdb_isMdbPowerOn(void) const override;
-
-    bool coid_isAttached(void) const override;
-    bool coin_escrowIsOpen(void) const override;
-
-    bool aux_isAuxPowerOn(void) const override;
-
-    uint8_t aux_getAuxInputs(void) const override;
-
-    bool mod_isGsmPowerOn(void) const override;
-
-    bool cred_isCreditPowerOn(void) const override;
-
-    bool cash_getRejectMotorHomePos(void) const override;
-
-    uint8_t cash_getLowPaperSensor(void) const override;
-        // 0: Sensor sees paper 1: no paper 99: off
-
-
-    // ------------------------------------------------------------------------------
-    // Level1,2,3     RD request commands
-    // ------------------------------------------------------------------------------
-
-    // all read-requests can be sent manually by the following functions
-    //   or automatically in background by:   void hwapi::dc_autoRequest(bool on)
-    //   in other words:
-    //   if automatic-reading is on, then there's no need to send any of these commands,
-    //    but it's allowed to send them in order to speed up the refreshing of the inputs
-
-    void request_DC2serialConfig() const override;
-    void request_DC2_HWversion() const override;
-    void request_DC2_SWversion() const override;
-    void request_DC2_condition() const override;
-    void request_DC2_UID() const override;
-    void request_DC2_TimeAndDate() const override;
-    void request_DC2_analogues() const override;
-    void request_DC2_digitalInputs() const override;
-    void request_DC2_digitalOutputs() const override;
-
-    // ------------------------------------------------------------------------------
-    // the folowing device state requests are deploed only if device is powered up:
-    void request_PrinterHwState() const override;
-    void request_PrinterCurrentFonts() const override;
-    void request_PrinterStateComplete() const override;
-
-    void request_MifareReaderState() const override;
-    void request_MifareCardType() const override;
-    void request_MifareAtbType() const override;
-    void request_MifareID() const override;
-    void request_MifareData(uint8_t dataBlockNumber) const override;
-        // dataBlockNumber must be 0....11, returns 64byte of data
-
-    void request_MDB_Status() const override;
-    void request_MDB_lastResponse() const override;
-    void request_EMP_allParameters() const override;
-    void request_EMP_lastCoin() const override;
-
-
-
-    // ------------------------------------------------------------------------------
-    // Level 3: readback digital outputs of connected devices
-    //          these functions are not needed for normal operation
-    //          but can be used to test and verify conditions
-
-    //          There are two options:
-    //              1) the important things like power-outputs and wake lines are
-    //              measured at DC2-terminals (after transistors) and come as input to DC-board
-    //              2) others like Leds are read from µC-pins by DC-board
-    // ------------------------------------------------------------------------------
-
-    bool test_getDO_mdbRXtst(void) const override;
-
-    uint8_t lock_getDO_motors(void) const override;
-        // bit0: upper lock forward    bit 1 backward
-        // bit2: lower lock forward    bit 3 backward
-
-    uint8_t test_serialState(void) const override;
-        // test on-board signals for the serials
-        // serial drv on/off, Serial mux1, Serial mux2
-    bool test_serialIsOn(void) const override;
-    bool test_serialMux1isSetToPrinter(void) const override;
-    bool test_serialMux1isSetToModem(void) const override;
-    bool test_serialMux2isSetToCredit(void) const override;
-    bool test_serialMux2isSetToMifare(void) const override;
-
-    bool led_coinIsOn(void) const override;
-    bool led_frontIsOn(void) const override;
-    bool led_ticketIsOn(void) const override;
-    bool led_pinIsOn(void) const override;
-    bool led_StartIsOn(void) const override;
-    bool led_insideIsOn(void) const override;
-
-    bool fan_isOn(void) const override;
-    bool siren_isOn(void) const override;
-    bool bar_relayIsOn(void) const override;
-    bool ptu_WakeOutIsOn(void) const override;
-
-    bool aux_powerIsOn(void) const override;
-
-    bool coin_shutterIsOpen(void) const override;
-    bool coin_shutterTestOutput(void) const override;
-
-    uint8_t coin_escrowFlapOpened(void) const override;
-        // retval: 1:return flap is open   2:take flap is open    0:closed
-
-
-
-    // ------------------------------------------------------------------------------
-    // Level4 ( Timer processes, device supervision by DC, processes with more then one devices
-    // WRITE
-    // ------------------------------------------------------------------------------
-
-
-    void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
-                            uint8_t kindOfMifareReader, uint8_t suppressSleep,
-                            uint8_t kindOfModem,        uint8_t kindOfCredit        ) const override;
-    // enable hardware in device controller:
-    // kindOfPrinter:       0:off 1: GPT4672 (only this one implemented)
-    // kindOfCoinChecker:   0:off 1:EMP820 2:EMP900 3: C²_changer
-    // kindOfMifareReader:  0:off 1: SL025   (only this one implemented)
-    // suppressSleep:       0:sleep allowed 1: sleep surpressed for special reason
-    // kindOfModem:         0:off 1: ATB_Sunlink_LTE        (not yet implemented)
-    // kindOfCredit:        0:off 1:  cVendTopp  2:cVendPin (not yet implemented)
-
-    void request_ReadbackDeviceSettings() const override;
-
-    void readback_DeviceSettings(uint8_t *length, uint8_t *data) const override;
-        // refer to DC2 manual for exact content
-        // state 5.5.21: byte[0]=kindOfPrinter   byte[1]=kindOfCoinChecker
-    //               byte[2]=kindOfMifarereadr   byte[3]=suppress sleep mode
-    //               byte[4]=kindOfModem         byte[5]=kind of cc terminal
-
-    uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const override;
-        // use for changer
-
-    void sendMachineID(uint16_t customerNr, uint16_t machineNr,
-                              uint16_t borough, uint16_t zone,
-                              uint16_t alias,   char *location) const override;
-
-    void request_ReadbackMachineID() const override;
-
-    void readback_machineIDdata(uint8_t *length, uint8_t *data) const override;
-    // state 5.5.21: byte[0,1]=customer number    byte[2,3]=machine number
-    //               byte[4,5]=borough   byte[6,7]=zone   byte[8,9]=alias name
-    //               byte[10...41]=location
-
-
-    // Locks stops automatically at end switch or by timeout
-    uint8_t lock_openUpperDoor(void) const override;
-    uint8_t lock_closeUpperDoor(void) const override;
-
-    uint8_t lock_openLowerDoor(void) const override;
-    uint8_t lock_closeLowerDoor(void) const override;
-
-
-    void shut_openOnce(void) const override;
-        // and close automatic after shutter time
-
-    void shut_openForCoin(bool start) const override;
-        // open flap if coin is attached
-        // once process is started it runs until stop command
-
-    void shut_sendOpeningTime(uint16_t timeIn_ms ) const override;
-        // after this time without retrigger the flap is closed
-
-    void esc_takeMoney(void) const override;
-        // and close automatically after escrow time (1s)
-
-    void esc_returnMoney(void) const override;
-        // and close automatically after escrow time (1s)
-
-    void mif_creatAtbCard(uint8_t cardType) const override;
-
-
-    // ------------------------------------------------------------------------------
-    // read response from DC2 (input data)
-    // ------------------------------------------------------------------------------
-
-    uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const override;
-        // retval 0=OK 1=error host buffer too small
-    /* data description, new fast version:
-    byte 0= still the same: 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: reader state 1=ok 0=nok
-    byte 2: card preent (0,1)
-    byte 3: card selected (0)
-    byte 4: card type: 0...5
-    byte 5: card allowed (0=no  1=MifareClassic 1k or 4k)
-    byte 6: CardSize: 1 or 4 (kB)
-    byte 7: length of UID 4 or 7 (byte)
-    */
-
-    bool mif_readerIsOK(void) const override;
-
-    bool mif_cardAttached(void) const override;
-
-    uint8_t mif_readResult(void) const override;
-        // result: 0: unknown or still in progress
-        //         1: card read successful
-        //         2: reading error
-
-    QString mif_cardUID(void) const override;
-
-    uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const override;
-
-    QString mif_getCardDataStr(uint8_t blockNumber) const override;
-        // with blockNumber=0...11
-
-
-
-
-    // ----------------------------------------------------------------------------------------------------------
-    // --------------------------------------------- PRINTER ----------------------------------------------------
-    // ----------------------------------------------------------------------------------------------------------
-
-    // read printer condition and settings
-
-    uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const override;
-        // retval: status byte
-            // byte 0 = 0: prnter OK,  >0: error
-            // bit0: paper low  1: no paper    2: temperature error
-            // 3: head open     4: paper jam in cutter
-            // 6: no response   7: bad response from printer
-        // and return struct "Tprn_hw_state"
-
-    bool prn_isUpAndReady(void) const override;
-        // true: printer is powered, serial is ok, no error, printer is connected and resonding
-
-    void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const override;
-
-
-    // send Commands to printer:
-
-    void prn_sendText(QByteArray *buf) const override;
-        // up to 1280 bytes
-
-    void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const override;
-        // send three byte through to printer, see printers manual
-
-    void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const override;
-        // send four byte through to printer, see printers manual
-
-
-    void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const override;
-        // send 5 byte: byte 0,1: speed  5...250 mm/s
-        //              byte2: density   0....(25)....50
-        //              byte3: alignment    'l', 'c', 'r' = left, center, right
-        //              byte4: orientation  0, 90, 180    = 0°, 90°, 180° rotation (by now not supported!)
-        // not batched! don't use twice within 100ms
-
-    void prn_movePaper(uint8_t wayInMm, uint8_t direction) const override;
-        //direction: 1=forward 2=backward
-        //
-    void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const override;
-        // font = kind of font 5...11 (0..22)
-        // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge
-        // width:  0...4   0=1x  1=2x   2=4x (huge!)  3=8x 4=16x (3,4 make no sense)
-        // heigth: 0...7 = 1x...8x  only 0,1,2,(3) make sense
-
-    void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const override;
-        // bold: 0/1
-        // invers: 0/1
-        // underlined: 0/1
-
-    void prn_cut(uint8_t kindof) const override;
-        // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut)
-
-    void prn_newLine(uint8_t nrOfLines) const override;
-
-    void prn_printCompleteFontTable(void) const override;
-
-
-    void prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const override;
-        // kind of barcode: 0=Code39   1=Code128   2=EAN13    3= 2/5interleaved    4=UPC-A   5=EAN8
-        // withText:    print readable text below
-        // offset: move by pixel from left border
-        // rotation
-        // dataLeng in byte
-
-    void prn_sendQRdata(QByteArray *buf) const override;
-        // maximal 150 alphanummeric bytes
-
-    void prn_printQRcode(void) const override;
-        // QRcode may have 1...150 alphanummeric data, must be transfered in advance
-
-
-    void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const override;
-        // nrOfLogo: 1..4 in flash  5...8 in Ram
-        // offset: in mm form left border
-
-
-
-    // .........................................................
-    // Parking Ticket (print-out document) designer TD
-    // .........................................................
-
-    // Predefine document Layout (e.g. parking ticket) in advance and stroe it for quick and easy use
-    // in opposite to the above "single" commands you need only one or a few commands at vending time.
-    // Stored text is just send to printer once the printing command is issued
-    // stored commands within the text are interpreted and executed right at the place (in ticket) they are
-    // example: start bold, <text in bold>, stop bold
-    // Predefinition of up to 16 ticket Layouts is possible, 0...1280 byte each
-    // Number 0..15, al keept non-volatile
-    // up to 8 dynamic values can be defined in the template ("print val3 here") and will be sent with printing command
-    // example: print current time at this point (the time of printing not the storage time!!)
-
-    void pri_startTicketDesign(void) const override;
-        // start for every new printer document, reseting collecting buffer
-
-    // all further functions write/append text, numbers and command to the ticket-buffer, up to 1278 bytes allowed
-    // return val of the appending functions: true=ok false=too long, buffer full
-
-    int pri_TD_getCurrentSize(void) const override;
-        // retval: 0...1278
-
-    bool pri_TD_addText(QByteArray text) const override;
-        // example: pri_TD_addText("Hello") const override;
-        // example: pri_TD_addText(tempStr) const override;
-        // retval: true=ok false=too long, buffer full
-
-    bool pri_TD_addValue(int val) const override;
-        // +/- 0...2^(31)
-
-    bool pri_TD_addNewLine(void) const override;
-
-    bool pri_TD_addSign(char sign) const override;
-        // example: '.'   ' '   0x20 'W' '$'
-
-    bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const override;
-        // always add 8 byte to the ticket layout:  ESC & group & attribute & parameter1...5
-        /* complete list of possible commands:
-            group 50 : paper
-                attribute 10 :  move forward
-                      p1: wayInMm p2: direction
-                attribute 11 : cut
-                      p1: kind of, 1=full 2=partial, 3=eject
-                attribute 12 : new line(s)
-                      p1: nr of lines 1...100
-
-            group 51 : fonts
-                attribute 10 : kind of font     see description above
-                      p1: 0...8
-                attribute 11 : font size
-                      p1: 6...20
-                attribute 12 : font width
-                      p1: 0...4
-                attribute 13 : font heigth
-                      p1: 0...7
-                attribute 14 : switch bold print on/off
-                      p1: 0=off  1=on
-                attribute 15 : switch invers print on/off
-                      p1: 0=off  1=on
-                attribute 16 : switch underlined print on/off
-                      p1: 0=off  1=on
-
-            group 52 : print graphics
-                attribute 10 : print barcode with dynamic data 6 and 7
-                      p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above
-                attribute 11 : print QRcode with preset data
-
-                attribute 12 : print Logo
-                     p1=nrOfLogo, p2=offset
-
-            group 53 : print dynamics
-                attribute 10 :
-                        p1: 1...8 = print dynData 0..7 at this place
-
-    */
-
-    char prn_clearDocument(uint8_t documentNumber) const override;
-        // clear memory buffer for ONE document
-        // function takes a second! don't send right before "store doc"
-
-    bool prn_store_Document(uint8_t documentNumber ) const override;
-
-        // send the predefined Layout (generated with above TD functions) to DeviceController to save
-        // documentNumber=0...15
-        // maximal 1280 bytes each
-        // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc)
-        // 0x1B=start of embedded command (next 7bytes = command)
-
-    // with a print command a set of 8 dynamic strings can be sent
-    // the place in the ticket layout is predefined (already in DC memory)
-    // the dynamics are first calculated at printing time
-
-    bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const override;
-
-
-
-
-
-    // ----------------------------------------------------------------------------------------------------------
-    // --------------------------------------------- MDB Bus ----------------------------------------------------
-    // ----------------------------------------------------------------------------------------------------------
-
-    //void mdb_switchPower(bool on) const override;            defined above
-    //void mdb_switchWake(bool WAKEACTIVE) const override;     defined above
-//    bool mdb_WakeINisActive(void) const override;
-//    bool mdb_testIsmdbTxDon(void) const override;
-//    bool mdb_isMdbPowerOn(void) const override;
-//    void request_MDB_Status() const override;
-//    void request_MDB_lastResponse() const override;
-
-
-    void mdb_sendBusReset(void) const override;
-
-    void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const override;
-        // send one bus command directly over mdb bus, refer to mdb manual for commands
-        // this command is not needed in normal operation, just for new or special things
-
-    void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const override;
-        // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
-        // same as mdb_sendCommand, just with data
-
-    bool mdb_busIsReadyToWork() const override;
-
-    bool mdb_deviceVoltageOK() const override;
-
-    bool mdb_busVoltageOk() const override;
-
-    uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
-                                      uint8_t *responseLength, uint8_t *responseBuffer) const override;
-        // fromDevice: device nr from which data was requested 0,1,2,3
-        // lastRequest: sent mdb command
-        // responseLength: nr of payload data (after mdb-ack) 0...34
-        // responseBuffer holds payload data (answer from mdb device)
-        // return val: mdb result of this request: 1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
-
-
-
-
-
-    // ----------------------------------------------------------------------------------------------------------
-    // ---------------------------------- Electronic Coin Validator EMP -----------------------------------------
-    // ----------------------------------------------------------------------------------------------------------
-
-
-    void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const override;
-        // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
-        // tokenChannel 0...31: if this signal comes from emp then a token was inserted
-        // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
-
-    void emp_pollingOnOff(uint8_t on) const override;
-
-    void emp_startCoinAcceptance(void) const override;
-
-    void emp_stopCoinAcceptance(void) const override;
-
-    void emp_getAllParameters(struct T_emp *emp) const override;
-        // see struct in hwapi.h
-        // usage example:
-        //      hwapi   *HWaccess const override;
-        //      HWaccess = new hwapi() const override;
-        //      struct T_emp   myEmp const override;
-        //      HWaccess->emp_getAllParameters(&myEmp) const override;
-        //          readval=myEmp.pollingRunning const override;
-
-    uint8_t emp_chkIfCoinInserted(void) const override;
-        // retval: 0...16 coins left in FIFO
-
-    void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const override;
-        // with every call ONE coin is taken out of FIFO and pointer decremented
-        // valid: should be 1
-        // signal: comes right from coin checker, 0...15 (0=first programmed coin type) 0xFF=no signal
-        // error: was reported from EMP as dynamic signal right after coin insertion (instead of
-        //          coin signal), example: 3=unknown coin  4=coin is blocked by host.  0xFF=no error
-        // value: of the coin. Depends on parameter "coinDenomination" in function "emp_sendSettings"
-        //          if coinDenomination[coin 0..15] = 0 then the value programmed in coin checker is taken
-        //          if coinDenomination > 0 then this value is taken.
-        //          Useful in case of two currencies (adapt to local currency) or for token.
-
-    // function gives more details as "emp getLastCoin()" but "emp getLastCoin()" is easier to use
-
-    // alternativ to emp_getNewCoinRecord( ):
-    uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const override;
-        // retval: 0: NO coin stored  1: valid coin  2: got wrong coin or coin denied
-        // value: if retval1: value of the coin if reval=2: error number
-        //          0xFF means NO error or NO signal  (as 0 is a valid error/signal)
-        // signal: channel nr reported from checker 0...15
-
-
-
-
-
-// neu, 25.3.23
-
-    void bl_rebootDC(void) const override;
-
-    void bl_startBL(void) const override;
-    bool bl_checkBL(void) const override;
-    bool bl_isUp(void) const override;
-        // return true is bl is up and running
-        // also initializes "sendFile"
-
-    void bl_sendAddress(uint16_t blockNumber) const override;
-        // send start address, nr of 64byte-block, start with 0
-        // will be sent only for folling block-numbers:
-        // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
-
-    uint8_t bl_wasSendingAddOK(void) const override;
-    // return val: 0: no response by now  1:error  10: OK
-
-    void bl_openBinary(void) const override;
-
-    void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const override;
-    // send 64 byte from bin file
-
-    void bl_sendLastBlock(void) const override;
-
-    uint8_t bl_wasSendingDataOK(void) const override;
-    // return val: 0: no response by now  1:error  10: OK
-
-    void bl_stopBL(void) const override;
-
-
-    // Bootlader, not used or obsolete
-    //bool bl_isDiagAvailable(void) const override;
-    //QString dc_getDiagText(void) const override;
-    //void bl_startSending(void) const override;
-    //void bl_sendFile(void) const override;
-
-
-
-// neu, ab 6.4.23
-// bereits vorhanden, nochmal getestet/verbessert:
-    // void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const override;
-    // void alarm_switchSiren(bool on) const override;
-
-    // void mif_readerOn(bool on) const override;
-    // bool mif_cardIsAttached(void) const override;
-
-    // void shut_move(bool open) const override;
-    // void esc_moveFlaps(uint8_t flap ) const override;
-        // 0: close both  1: open take-flap   2: open return
-    // void shut_openOnce(void) const override;
-        // and close automatic after shutter time
-    // void shut_openForCoin(bool start) const override;
-        // open flap if coin is attached
-        // once process is started it runs until stop command
-    // void shut_sendOpeningTime(uint16_t timeIn_ms ) const override;
-        // after this time without retrigger the flap is closed
-    // void esc_takeMoney(void) const override;
-        // and close automatically after escrow time (1s)
-    // void esc_returnMoney(void) const override;
-        // and close automatically after escrow time (1s)
-
-    // void prn_switchPower(bool on) const override;
-    // void prn_sendText(QByteArray *buf) const override;
-        // up to 1280 bytes
-
-    // uint8_t rtc_setDateTime(void) const override;
-            // send system time
-
-    //void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
-    //                        uint8_t kindOfMifareReader, uint8_t suppressSleep,
-    //                        uint8_t kindOfModem,        uint8_t kindOfCredit        ) const override;
-
-    //void sendMachineID(uint16_t customerNr, uint16_t machineNr,
-    //                          uint16_t borough, uint16_t zone,
-    //                          uint16_t alias,   char *location) const override;
-
-    /*
-    uint8_t emp_getInsertedCoinSignal(void) const override;
-        // can be called one time after each coin
-        // emp_chkIfCoinInserted() must be called before!
-
-    uint16_t emp_getInsertedCoinValue(void) const override;
-        // can be called one time after each coin
-        // emp_chkIfCoinInserted() must be called before!
-
-    uint8_t emp_getCoinError(void) const override;
-        // can be called one time after each coin
-        // emp_chkIfCoinInserted() must be called before!
-    */
-
-    bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const override;
-        // return true if successful. could fail if more the 8 commands are waiting
-
-    bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const override;
-
-    bool sys_runCompleteTest(void) const override;
-        // warning: lasts 20s in one pace
-
-    bool sys_ready4sending(void) const override;
-    // return true if a Json-file can be sent
-
-    bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const override;
-        // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
-        //      nrOfTemplate=1...32 if kindOfFile==6
-        //      content = content of the Json file, max 800byte ascii signs
-        // file is 0-terminated!
-        // return false if sending is not possible, wait a second
-
-    bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const override;
-    // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string
-    //            like:     char prn_dynPrnVal[8][8];
-    // return true if sending, false if cmd-stack is full
-
-    bool prn_printTemplate(uint8_t nrOftemplate) const override;
-        // print one of the templates loaded by Json prior
-        // nr = 1..32
-        // return true if sending, false if cmd-stack is full
-
-    void log_getHoldAccountNumbers(uint32_t *accNr ) const override;
-        // returns all acc nrs of the backuped vault records
-        // use: uint32_t backupedAccNumbers[8]
-
-    bool log_selectVaultRecord(uint16_t accountNr ) const override;
-        // return true if sending, false if cmd-stack is full
-
-//request, isAvailable
-    void log_getVaultRecord(struct T_vaultRecord *retVR) const override;
-        // which was selected by: log_selectVaultRecord()
-        // to be forwarded to Ismas
-
-    bool prn_printAccountReceipt(void) const override;
-        // return true if sending to DC OK, false if cmd-stack is full
-
-    bool prn_printTestTicket(void) const override;
-        // return true if sending to DC OK, false if cmd-stack is full
-
-    bool cash_startPayment(uint16_t amount) const override;
-
-    bool cash_cancelPayment(void) const override;
-        // and return coins
-
-    bool cash_stopPayment(void) const override;
-        // and keep coins in escrow
-
-    uint32_t getInsertedAmount(void) const override;
-
-    uint16_t getLastInsertedCoin(void) const override;
-
-    bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const override;
-        // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64
-
-
-    // after ticket/goods issue:
-    bool vend_success(void) const override;
-        // conclude payment process, encash all inserted coins to vault. Printing was successful
-        // if possible return change
-
-    bool vend_failed(void) const override;
-        // conclude payment process and return all inserted coins
-
-
-
-
-
-    uint8_t mif_getCardType(QString cardholder) const override;
-        // return 1,2,3,4 = upper, lower access card, printer test, coin test
-        // cardholder: 7byte Name-String
-
-    uint64_t sys_getWakeSource(void) const override;
-        // retval: 6 bytes, bit coded, 1=event keeps DC awake
-
-    //void sys_getDeviceConditions(struct T_moduleCondition *devCond) const override;
-    void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const override;
-
-    //void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const override;
-    void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const override;
-
-
-
-
-
-private:
-    void sub_storeSendingText(QByteArray *buf) const;
-
-
-
-
-
-
-};
-
-
-#endif
-
-
-
-/*
-    // Coin checker and changer mdb4.2 / section 5
-    // Level 2 Commands  (predefined device msg acc. mdb manual and auto-poll)
-    uint8_t mdb_coin_startPolling(bool on) const override;    // send ether one command (from list below)
-                                               // or a poll command in the proper polling grid (e.g. every 100ms)
-    uint8_t mdb_coin_reset() const override;
-    uint8_t mdb_coin_setup() const override;
-    uint8_t mdb_coin_tubestatus() const override;
-    uint8_t mdb_coin_pollManually(void) const override;
-    uint8_t mdb_coin_type(uint16_t coinEnable, uint16_t dispenseEnable) const override;
-    uint8_t mdb_coin_dispense(uint8_t disp) const override;
-    uint8_t mdb_coin_expansion(uint8_t subCmd, uint8_t send[32]) const override;
-    uint8_t mdb_coin_getResponse(void) const override;
-            // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
-    uint8_t mdb_coin_getDataLen(void) const override;
-        // return nr of byte received from any mdb device
-    uint8_t mdb_coin_getData(uint8_t *mdb_data, uint8_t maxBufferSize) const override;
-
-
-
-    // Bill validator       // section 6
-    uint8_t mdb_bill_startPolling(bool on) const override;
-    uint8_t mdb_bill_reset() const override;
-    uint8_t mdb_bill_setup() const override;
-    uint8_t mdb_bill_security(uint16_t secLevel) const override;
-    uint8_t mdb_bill_pollManually(void) const override;
-    uint8_t mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable) const override;
-    uint8_t mdb_bill_escrow(uint8_t action) const override;
-    uint16_t mdb_bill_stacker(void) const override;
-    uint8_t mdb_bill_expansion(uint8_t subCmd, uint8_t send[32]) const override;
-    uint8_t mdb_bill_gotPollResponse(void) const override;
-            // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
-    uint8_t mdb_bill_getDataLen(void) const override;
-    uint8_t mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize) const override;
-
-
-
-    // Level 3 Commands - all cash devices are used together and automatically
-    // -->easiest way to use
-
-    // setting up payment:
-    uint8_t cash_getAcceptance(struct Tcash_state *cash_state) const override;
-        // return device specific parameters, (e.g. which tubes are installed)
-        // to be requested before/after payment
-    uint8_t cash_setMaxReturn(uint32_t amount) const override;         // Security Limit
-    uint8_t cash_setMaxAcceptance(uint32_t amount) const override;     // can pay up to this amount
-        // example: set to 12€ (=max price step), then the 3rd 5€ bill would be kept in escrow
-        // or with coins: max. insertable = 13,95€ (11,95€ is still <12€, plus a 2€-coin)
-    uint8_t cash_setCoinsToBeAccepted(uint16_t coinVal[2][16]) const override;
-        // up to 16 coins per currency in one or two currencies
-        // [0]=first currency, e.g. Huf  [1]=2nd, like euros
-    uint8_t cash_setBillsToBeAccepted(uint32_t billVal[2][16]) const override;
-    uint8_t cash_setOpeningTime(uint16_t opentime_100ms) const override;       // coin slot is opening/closing automatically
-    uint8_t cash_setWaitForLastCoinTime(uint16_t lastCoinTime_100ms) const override;
-        // while this time coin/bill aceptance is still active after "disable payment" command
-    uint8_t cash_getAllsettings(struct TcashSettings cashSettings) const override;
-        // return all above set own parameters
-
-    // starting payment
-    uint8_t cash_powerUp(bool on) const override;              // power up/down devices (bill takes up to 3s)
-    uint8_t cash_enablePayment(bool start) const override;     // start/stop accepting bills and coins
-
-    // running payment
-    bool    gotNewCoinBill(void) const override;                    // true on every insertion, only once
-    uint8_t cash_getInserted(struct Tcash_pay *payment_state) const override;
-
-    // finishing payment
-    uint8_t cash_coinEscrowTake(void) const override;
-    uint8_t cash_coinEscrowReturn(void) const override;
-    uint8_t cash_return(uint32_t amount) const override;
-*/
-
-
-/*
-    uint8_t cc_setCondition(uint16_t chgCmd) const override;      // e.g. change to state registered, sleep, open, off....
-    uint16_t cc_getCondition(void) const override;                // e.g. now socket open
-    bool    cc_sendBufferFree(void) const override;               // sending allowed (before writing) and sending finished (after writing)
-    uint8_t cc_sendDataBlk(uint16_t len, uint8_t *buf) const override;
-    void    cc_wantReadData(uint16_t nrOfData) const override;                        // start reading
-    uint16_t cc_gotData(void) const override;                             // return nr of received bytes
-    uint8_t cc_loadDataBlk(uint16_t len, uint8_t *buf) const override;
-    uint8_t cc_getWorkFlow(void) const override;
-        // off, activated, gotStart_wait4card, wait4pin, gotPin, callingBank, CardAccepted.....
-    uint8_t cc_setupSerial(struct TserialParams serialParameter) const override;
-    uint8_t cc_getCurrentSerialSettings(struct TserialParams *serialParameter) const override;
-*/
-
-
-/*
-
-struct TcashSettings
-{
-    uint32_t MaxReturnAmount const override;
-    uint32_t MaxAcceptAmount const override;
-    uint32_t CoinsAcceptedCur[2][16] const override;
-    uint32_t BillsAcceptedCur[2][16] const override;
-    uint32_t availableReturnAmount const override;
-
-} const override;
-
-
-struct Tcc_hw_state
-{
-    bool powerRdBk const override;     // prn pwr is on
-    bool rsSwOk const override;        // serial switch (printer or modem) is set to CreditCard (iUC)
-    bool rsDrvOk const override;       // RS232 converter for PTU, Printer and Modem in on
-    uint8_t HwState const override;    // idle, off, on, ready
-    bool gotAnswer const override;     // cable OK?
-    uint8_t moduleType const override;
-    uint8_t protocolType const override;
-
-} const override;
-
-
-*/
-
-
-/*
-    // not yet implemented
-    uint8_t mod_power(bool on) const override;
-    uint8_t mod_getHwState(struct Tmod_hw_state *mod_hw_state) const override;
-    uint8_t mod_setCondition(uint16_t chgCmd) const override;      // e.g. change to state registered, sleep, open, off....
-    uint16_t mod_getCondition(void) const override;                // e.g. now socket open
-    bool    mod_sendBufferFree(void) const override;               // sending allowed (before writing) and sending finished (after writing)
-    uint8_t mod_sendDataBlk(uint16_t len, uint8_t *buf) const override;
-    void    mod_wantReadData(uint16_t nrOfData) const override;                        // start reading
-    uint16_t mod_gotData(void) const override;                             // return nr of received bytes
-    uint8_t mod_loadDataBlk(uint16_t len, uint8_t *buf) const override;
-    uint8_t mod_setupSerial(struct TserialParams serialParameter) const override;
-    uint8_t mod_getCurrentSerialSettings(struct TserialParams *serialParameter) const override;
-
-    // Credit Card Terminal:
-    uint8_t cc_power(bool on) const override;
-    uint8_t cc_getHwState(struct Tcc_hw_state *cc_hw_state) const override;
-
-*/
-
+/*
+matching interfaces.h:
+
+// History
+// 11.10.2021: V1.0  222 functions
+// 23.12.2021: V1.1  added block-parameter to function "read mifare data"
+// 30.12.2021: V1.2  added function: mif_clearDataBuffer(), mif_isBlockAvailable(uint8_t blkNr) and mif_getAvailableDataBlocks()
+// 1.1.2022: V1.3    Mifare extended. ( background: read 16 x 48byte from card to DC, read 12 x 64byte from DC to CA)
+//                   new:  read full card with 768bytes from HWapi without block borders
+//                   added: mif_getNrOfAvailableDataBytes     mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize)
+//                           mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize)
+//                            mif_getCardDataStr(bool useHexFormat, char seperator)
+// 29.03.2023: V3.1 some extensions for PSA1256_ptu5,
+//             V3.2 Bootloader improvement
+// 12.04.2023: V3.3 new features extended: loading and using Json-files, cash-collection, cash-data-logging
+
+//#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1"
+//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.1"
+#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.3"
+
+
+PSA1259 hardware control using the DeviceController DC2
+
+covering enclosure (switches and doors) and money devices,
+controls mifare card to access or program
+optional it can control printer, modem, bar code reader and credit card
+
+ * API to the PSA1259 Hardware
+ * All data come in from device controller via serial interface and will be stored
+ * in "PI" = peripheral image
+ * PI is updated every 100ms (up to 30ms possible)
+ * This api uses stored pi data and returns them in the following functions
+ * created: Q1/2020 TS
+ *
+
+The devices, connected to device controller2 (DC2) can be controlled in different access levels.
+Level 1:
+    direct connection to DC2, check versions, state and parameters
+    control serial interfaces
+    digital/analog IO's
+    read and write to connected devices on lowest level, this is a kind of fall-back-level
+    in case higher levels fail or do not support the needed (new) function
+    Example: send a specific printer command, several bytes that need to be conform to
+            printer manual. This command is routed to the printer through the DC2 without
+            any action of the DC. You can write your own device driver that way.
+    Level 1 is flexible but complicated
+
+Level 2:
+   The DC controls the connected devices containing a device driver. The DC offers
+   usage of the device by simple commands,
+   Example: "Printer on", "set Font size 3" "print "hello world"", "cut"
+   In opposite to level 1 where you had to send a set of numbers and letters.
+   In other words: you "talk" to the device controller, not to the device itself.
+
+Level 3:
+    start/stop complete processes.
+    Example: 1) print (predefined) document nr 3 with Text, letter size, font set, cut.
+                Also power up/down the printer, check if paper ok and so on.
+*/
+
+/*
+Another access example: control the coin unit
+
+Level 1): read digital inputs to detect coin,
+          switch digital output which opens coin slot
+          communicate with coin checker by certain mdb-commands (manual conform)
+          poll coin checker for inserted coins
+          close coin slot after 3seconds by setting DO to 0....
+
+Level 2): get message of attached coin from DC
+          send command "initialize coin checker" to DC
+          send command "open slot for 3s"
+          poll DC for inserted coins, DC polls coin checker in right way, no need
+                to know the data sheet of the coin checker or mdb-bus
+          command to DC "open coin escrow's return flap for 1s"
+
+Level 3): send command: "start payment process"
+          all coin devices are started up
+          coin blocker opens for 3s if a coin is attached
+          coin checker summarizes inserted value and reports sum
+          later send command "stop payment process" (puts coins to vault) or
+          send command "cancel payment process" (returns coins to user)
+
+*/
+
+#ifndef hwapi_H
+#define hwapi_H
+
+#include <stdint.h>
+#include <QTabWidget>
+#include <QtPlugin>
+#include <QObject>
+#include "interfaces.h"
+#include "datIf.h"
+
+
+
+class hwapi :   public QObject,
+                public hwinf
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "Atb.Psa2020.software.HWapi/1.0" )   //FILE "HWapi.json")
+    Q_INTERFACES(hwinf)
+
+    DownloadResult sendNextAddress(int bNum) const;
+    DownloadResult sendNextDataBlock(QByteArray const &b, int bNum) const;
+    DownloadResult sendStatus(int ret) const;
+    DownloadResult dc_downloadBinary(QByteArray const &binary) const;
+
+    bool startBootloader() const;
+    bool stopBootloader() const;
+    bool openSerial(int br, QString baudrate, QString comPort) const;
+    bool closeSerial(QString comport) const;
+    bool resetDeviceController() const;
+    QByteArray loadBinaryDCFile(QString filename) const;
+    bool downloadBinaryToDC(QString const &bFile) const;
+public:
+    explicit hwapi(QWidget *parent = nullptr);
+
+    T_datif *myDatif;
+
+
+    // ------------------------------------------------------------------------------
+    // Level 0 commands, interface
+    // open, close, change serial interface
+    // actually not neccessary as it is opened automatically on program start
+    // start automatic READ requests
+    // ------------------------------------------------------------------------------
+
+    bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const override;
+        // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
+        // BaudStr: for exapmle "19200"
+        // ComName: for example "COM48"
+        // connect: 0, 1
+
+    bool dc_closeSerial(void) const override;
+
+    bool dc_isPortOpen(void) const override ;
+
+    void dc_autoRequest(bool on) const override ;
+        // select if READ-Requests are sent manually one by one or automatically
+        // automatically request ALL digital and analog sensors, get time/date, get status information
+
+    bool dc_updateDC(QString binFileName, QString baudrate,
+                     QString comPort) const override;
+    
+    bool dc_updatePrinterTemplate(enum FileTypeJson type,
+                                  QVector<int> templateIdx,
+                                  QVector<QString> fnames,
+                                  QString br,
+                                  QString serial = QString()) const override;
+
+    bool dc_printTemplate(enum FileTypeJson type,
+                          QVector<int> templateIdx,
+                          QString br,
+                          QString serial = QString()) const override;
+    // ------------------------------------------------------------------------------
+    // Level 1, control device-controller (functions of µC)
+    // check serial connection to deviceController
+    // read response from DC2 (input data)
+    // some test function for serial communication
+    // also Bootloader is here
+    // ------------------------------------------------------------------------------
+
+    void dc_requTestResponse() const override;
+        // tell DC2 to return his TestString in order
+        //   to test the serial and the baudrate
+        // must always be triggered manually, is never sent automatically
+
+    bool dc_readAnswTestResponse() const override;
+        // retval: true: test was successful, got right response
+
+    uint8_t dc_isRequestDone(void) const override;
+        // retval:  0: request is still in progress
+        //          1: answer from DC2 was OK
+        //          2: wrong answer from DC2
+
+    uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const override;
+        // get data back in *pl, max 64 byte, can be used for diagnosis
+        // 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
+
+    void dc_setWakeFrequency(uint8_t period) const override;
+        // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
+        // change wake signal period to 1...64s
+
+    void dc_OrderToReset(void) const override;
+        // want DC2 to reset (in order to start Bootloader)
+
+    QString dc_getSerialState(void) const override;
+    void dc_clrSerialStateText(void) const override;
+
+    void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const override;
+        // send without protocol frame, needed for the DC bootloader
+
+    uint8_t getRawRecLength(void) const override;
+
+    uint8_t getRawReceivedData(uint8_t *receivedData) const override;
+
+    QString dc_getSerialParams(void) const override;
+
+    QString dc_getHWversion(void) const override;
+
+    QString dc_getSWversion(void) const override;
+
+    QString dc_getState(void) const override;
+
+    QString dc_getTxt4RsDiagWin(void) const override;
+    void dc_clrTxt4RsDiagWin(void) const override;
+    QString dc_get2ndTxt4RsDiagWin(void) const override;
+    void dc_clr2ndTxt4RsDiagWin(void) const override;
+    QString dc_getTxt4HsStateLine(void) const override;
+    void dc_clrTxt4HsStateLine(void) const override;
+    QString dc_getTxt4masterStateLine(void) const override;
+    void dc_clrTxt4masterStateLine(void) const override;
+    QString dc_getTxt4resultStateLine(void) const override;
+    void dc_clrTxt4resultStateLine(void) const override;
+    QString dc_getdataStateLine(void) const override;
+    void dc_clrTxt4dataStateLine(void) const override;
+    QString dc_getdatifLine(void) const override;
+    void dc_clrTxt4datifLine(void) const override;
+
+    // using DC2 Bootloader
+    void bl_iniChain(void) const override;
+    bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const override;
+    uint8_t bl_activatBootloader(uint8_t *sendData) const override;
+    uint8_t bl_startChain(void) const override;
+    uint8_t bl_readBLversion(uint8_t *sendData) const override;
+        // minimum size of sendData-buffer: 5byte  retval: length
+    uint8_t bl_readFWversion(uint8_t *sendData) const override;
+        // minimum size of sendData-buffer: 5byte  retval: length
+
+    uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const override;
+        // 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 bl_exitBL(uint8_t *sendData) const override;
+        // minimum size of sendData-buffer: 5byte  retval: length
+
+    // ------------------------------------------------------------------------------
+    // Level 2  DC2-onboard devices
+    //          WR: set time
+    //          RD. get time, get measure, get test results
+    // ------------------------------------------------------------------------------
+
+    // get UID, get time/date   test results   memory,  RTC  analog values
+/*
+    struct Trtc_DateTime
+    {
+        uint8_t rtc_hour;
+        uint8_t rtc_min;
+        uint8_t rtc_sec;
+        uint8_t rtc_dayOfMonth;
+        uint8_t rtc_month;
+        uint8_t rtc_year;
+        uint8_t rtc_dayOfWeek;
+    };
+*/
+    uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const override;
+
+    uint8_t rtc_setDateTime(void) const override;
+        // synch DC2 with PC or PTU system time and date
+
+    void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const override;
+        // get time directly
+
+    void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const override;
+        // get date directly
+
+    uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const override;
+        // dow=day of week, 1=monday...7
+        // minOfToday: 0=midnight...1439= 23:59
+        // secOfToday: 0=midnight...86399= 23:59:59
+
+    bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const override;
+        // retval true: this year is leap year
+
+    bool rtc_isLeapYear() const override;
+
+    void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const override;
+        // DayOfWeek: 1=monday...7
+        // HoursOfWeek: 0=Monday 0:00 o'clock...167=Sunday 23:00
+        // MinutesOfWeek: 0=Monday 0:00 o'clock...10079=Sunday 23:59
+
+    void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const override;
+        // DayOfMonth: 1...31
+        // HoursOfMonth: 0 = 0:00o'clock of 1.day in month     up to 743
+        // MinutesOfMonth:0 = 0:00o'clock of 1.day in month     up to 44639
+
+    void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const override;
+        // DayOfYear: 1...366  1= 1.Jan of this current year
+        // HoursOfYear: 0=1.Jan 0:00o'clock ...8783=31.12 23 o'clock
+        // MinutesOfYear: 0=1.Jan 0:00o'clock ...527039=31.12 23:59 o'clock
+
+    QString rtc_getTimStr(void) const override;
+    QString rtc_getDatStr(void) const override;
+    QString rtc_getTimDatStr(void) const override;
+
+    // UID
+    void     dc_getUID8byte(uint8_t *buf8byteUid) const override;
+    QString  dc_getUIDstr() const override;
+    uint64_t dc_getUIDnumber(void) const override;
+
+
+    // Analog inputs:
+    uint32_t dc_getTemperature(void) const override;       // in Sax-Format 0...400 (0=-50,0°C    100=0,0°C    141=20,5°C    400=150,0°C)
+    QString  dc_getTemperaturStr(void) const override;
+
+    uint32_t dc_getVoltage(void) const override;           // in mV,  0...65,535V
+    QString  dc_getVoltagStr(void) const override;
+
+    bool dc_mainFuseIsOk(void) const override;
+
+    // ------------------------------------------------------------------------------
+    // Level 3: digital outputs and simple switching of connected devices
+    //          simple processes like flashing a led or open flap for 1s
+    // ------------------------------------------------------------------------------
+
+    void lock_switchContactPower(bool on) const override;
+
+    // Locks move until stop cmd (0)
+    uint8_t lock_switchUpperLock(uint8_t dir) const override;
+        // dir 0=off 1=up 2=down
+    uint8_t lock_switchLowerLock(uint8_t dir) const override;
+        // dir 0=off 1=up 2=down
+    void lock_switchVaultDoor(void) const override;
+
+    void coin_switchRejectMotor(uint8_t dir) const override;
+
+    void coin_rejectCoins(void) const override;
+
+    // LEDs
+    void led_switchLedIllumination(uint8_t on) const override;
+    void led_switchLedService(uint8_t on) const override;
+    void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const override;
+    void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const override;
+    void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const override;
+    void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const override;
+
+    void fan_switchFan(bool on) const override;
+    void alarm_switchSiren(bool on) const override;
+    void bar_OpenBarrier(bool open) const override;
+    void ptu_switchWake(bool WAKEACTIVE) const override;
+
+    void prn_switchPower(bool on) const override;
+
+    void mif_readerOn(bool on) const override;
+    void shut_move(bool open) const override;
+    void esc_moveFlaps(uint8_t flap ) const override;
+        // 0: close both  1: open take-flap   2: open return
+
+    void mdb_switchPower(bool on) const override;
+    void mdb_switchWake(bool WAKEACTIVE) const override;
+
+    void mod_switchPower(bool on) const override;
+    void credit_switchPower(bool on) const override;
+
+    void aux_power(bool on) const override;
+    void aux_setUsage(uint8_t PinDirection) const override;
+    void aux_setOutputs(uint8_t PinIsHigh) const override;
+
+
+    void mod_switchWake(bool WAKEACTIVE) const override;
+
+    void credit_switchWake(bool WAKEACTIVE) const override;
+
+
+
+
+    // ------------------------------------------------------------------------------
+    // Level 3: digital inputs of connected devices
+    // ------------------------------------------------------------------------------
+
+    bool door_isContactPowerOn(void) const override;
+
+    uint8_t door_getSwitches(void) const override;
+        // retval:  bit0: upper door  1: low door  2:vault door
+
+    bool    door_isUpperDoorOpen(void) const override;
+
+    bool    door_isLowerDoorOpen(void) const override;
+
+    bool    vault_isVaultDoorOpen(void) const override;
+
+    uint8_t vault_getSwitches(void) const override;
+        // retval bit0: cash box,  bit 1: bill box
+
+    bool    vault_isCoinVaultIn(void) const override;
+
+    bool    vault_isBillVaultIn(void) const override;
+
+    uint8_t door_getLocks(void) const override;
+        // retval bit0: upper lever is up
+        //        bit1: upper lever is down
+        //        bit2: lower lever is up
+        //        bit3: lower lever is down
+
+    bool door_upperDoorIsLocked(void) const override;
+
+    bool door_upperDoorIsUnlocked(void) const override;
+
+    bool door_lowerDoorIsLocked(void) const override;
+
+    bool door_lowerDoorIsUnlocked(void) const override;
+
+    bool bar_optoIn1isOn(void) const override;
+
+    bool bar_optoIn2isOn(void) const override;
+
+    bool ptu_WakeINisActive(void) const override;
+
+    bool prn_isPrinterPowerOn(void) const override;
+    uint8_t prn_PrnFuseIsOk(void) const override;
+    //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off
+
+    bool prn_readyINisActive(void) const override;
+
+    bool mif_cardIsAttached(void) const override;
+    bool mif_isMifarePowerOn(void) const override;
+
+    bool mdb_WakeINisActive(void) const override;
+    bool mdb_testIsmdbTxDon(void) const override;
+    bool mdb_isMdbPowerOn(void) const override;
+
+    bool coid_isAttached(void) const override;
+    bool coin_escrowIsOpen(void) const override;
+
+    bool aux_isAuxPowerOn(void) const override;
+
+    uint8_t aux_getAuxInputs(void) const override;
+
+    bool mod_isGsmPowerOn(void) const override;
+
+    bool cred_isCreditPowerOn(void) const override;
+
+    bool cash_getRejectMotorHomePos(void) const override;
+
+    uint8_t cash_getLowPaperSensor(void) const override;
+        // 0: Sensor sees paper 1: no paper 99: off
+
+
+    // ------------------------------------------------------------------------------
+    // Level1,2,3     RD request commands
+    // ------------------------------------------------------------------------------
+
+    // all read-requests can be sent manually by the following functions
+    //   or automatically in background by:   void hwapi::dc_autoRequest(bool on)
+    //   in other words:
+    //   if automatic-reading is on, then there's no need to send any of these commands,
+    //    but it's allowed to send them in order to speed up the refreshing of the inputs
+
+    void request_DC2serialConfig() const override;
+    void request_DC2_HWversion() const override;
+    void request_DC2_SWversion() const override;
+    void request_DC2_condition() const override;
+    void request_DC2_UID() const override;
+    void request_DC2_TimeAndDate() const override;
+    void request_DC2_analogues() const override;
+    void request_DC2_digitalInputs() const override;
+    void request_DC2_digitalOutputs() const override;
+
+    // ------------------------------------------------------------------------------
+    // the folowing device state requests are deploed only if device is powered up:
+    void request_PrinterHwState() const override;
+    void request_PrinterCurrentFonts() const override;
+    void request_PrinterStateComplete() const override;
+
+    void request_MifareReaderState() const override;
+    void request_MifareCardType() const override;
+    void request_MifareAtbType() const override;
+    void request_MifareID() const override;
+    void request_MifareData(uint8_t dataBlockNumber) const override;
+        // dataBlockNumber must be 0....11, returns 64byte of data
+
+    void request_MDB_Status() const override;
+    void request_MDB_lastResponse() const override;
+    void request_EMP_allParameters() const override;
+    void request_EMP_lastCoin() const override;
+
+
+
+    // ------------------------------------------------------------------------------
+    // Level 3: readback digital outputs of connected devices
+    //          these functions are not needed for normal operation
+    //          but can be used to test and verify conditions
+
+    //          There are two options:
+    //              1) the important things like power-outputs and wake lines are
+    //              measured at DC2-terminals (after transistors) and come as input to DC-board
+    //              2) others like Leds are read from µC-pins by DC-board
+    // ------------------------------------------------------------------------------
+
+    bool test_getDO_mdbRXtst(void) const override;
+
+    uint8_t lock_getDO_motors(void) const override;
+        // bit0: upper lock forward    bit 1 backward
+        // bit2: lower lock forward    bit 3 backward
+
+    uint8_t test_serialState(void) const override;
+        // test on-board signals for the serials
+        // serial drv on/off, Serial mux1, Serial mux2
+    bool test_serialIsOn(void) const override;
+    bool test_serialMux1isSetToPrinter(void) const override;
+    bool test_serialMux1isSetToModem(void) const override;
+    bool test_serialMux2isSetToCredit(void) const override;
+    bool test_serialMux2isSetToMifare(void) const override;
+
+    bool led_coinIsOn(void) const override;
+    bool led_frontIsOn(void) const override;
+    bool led_ticketIsOn(void) const override;
+    bool led_pinIsOn(void) const override;
+    bool led_StartIsOn(void) const override;
+    bool led_insideIsOn(void) const override;
+
+    bool fan_isOn(void) const override;
+    bool siren_isOn(void) const override;
+    bool bar_relayIsOn(void) const override;
+    bool ptu_WakeOutIsOn(void) const override;
+
+    bool aux_powerIsOn(void) const override;
+
+    bool coin_shutterIsOpen(void) const override;
+    bool coin_shutterTestOutput(void) const override;
+
+    uint8_t coin_escrowFlapOpened(void) const override;
+        // retval: 1:return flap is open   2:take flap is open    0:closed
+
+
+
+    // ------------------------------------------------------------------------------
+    // Level4 ( Timer processes, device supervision by DC, processes with more then one devices
+    // WRITE
+    // ------------------------------------------------------------------------------
+
+
+    void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
+                            uint8_t kindOfMifareReader, uint8_t suppressSleep,
+                            uint8_t kindOfModem,        uint8_t kindOfCredit        ) const override;
+    // enable hardware in device controller:
+    // kindOfPrinter:       0:off 1: GPT4672 (only this one implemented)
+    // kindOfCoinChecker:   0:off 1:EMP820 2:EMP900 3: C²_changer
+    // kindOfMifareReader:  0:off 1: SL025   (only this one implemented)
+    // suppressSleep:       0:sleep allowed 1: sleep surpressed for special reason
+    // kindOfModem:         0:off 1: ATB_Sunlink_LTE        (not yet implemented)
+    // kindOfCredit:        0:off 1:  cVendTopp  2:cVendPin (not yet implemented)
+
+    void request_ReadbackDeviceSettings() const override;
+
+    void readback_DeviceSettings(uint8_t *length, uint8_t *data) const override;
+        // refer to DC2 manual for exact content
+        // state 5.5.21: byte[0]=kindOfPrinter   byte[1]=kindOfCoinChecker
+    //               byte[2]=kindOfMifarereadr   byte[3]=suppress sleep mode
+    //               byte[4]=kindOfModem         byte[5]=kind of cc terminal
+
+    uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const override;
+        // use for changer
+
+    void sendMachineID(uint16_t customerNr, uint16_t machineNr,
+                              uint16_t borough, uint16_t zone,
+                              uint16_t alias,   char *location) const override;
+
+    void request_ReadbackMachineID() const override;
+
+    void readback_machineIDdata(uint8_t *length, uint8_t *data) const override;
+    // state 5.5.21: byte[0,1]=customer number    byte[2,3]=machine number
+    //               byte[4,5]=borough   byte[6,7]=zone   byte[8,9]=alias name
+    //               byte[10...41]=location
+
+
+    // Locks stops automatically at end switch or by timeout
+    uint8_t lock_openUpperDoor(void) const override;
+    uint8_t lock_closeUpperDoor(void) const override;
+
+    uint8_t lock_openLowerDoor(void) const override;
+    uint8_t lock_closeLowerDoor(void) const override;
+
+
+    void shut_openOnce(void) const override;
+        // and close automatic after shutter time
+
+    void shut_openForCoin(bool start) const override;
+        // open flap if coin is attached
+        // once process is started it runs until stop command
+
+    void shut_sendOpeningTime(uint16_t timeIn_ms ) const override;
+        // after this time without retrigger the flap is closed
+
+    void esc_takeMoney(void) const override;
+        // and close automatically after escrow time (1s)
+
+    void esc_returnMoney(void) const override;
+        // and close automatically after escrow time (1s)
+
+    void mif_creatAtbCard(uint8_t cardType) const override;
+
+
+    // ------------------------------------------------------------------------------
+    // read response from DC2 (input data)
+    // ------------------------------------------------------------------------------
+
+    uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const override;
+        // retval 0=OK 1=error host buffer too small
+    /* data description, new fast version:
+    byte 0= still the same: 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: reader state 1=ok 0=nok
+    byte 2: card preent (0,1)
+    byte 3: card selected (0)
+    byte 4: card type: 0...5
+    byte 5: card allowed (0=no  1=MifareClassic 1k or 4k)
+    byte 6: CardSize: 1 or 4 (kB)
+    byte 7: length of UID 4 or 7 (byte)
+    */
+
+    bool mif_readerIsOK(void) const override;
+
+    bool mif_cardAttached(void) const override;
+
+    uint8_t mif_readResult(void) const override;
+        // result: 0: unknown or still in progress
+        //         1: card read successful
+        //         2: reading error
+
+    QString mif_cardUID(void) const override;
+
+    uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const override;
+
+    QString mif_getCardDataStr(uint8_t blockNumber) const override;
+        // with blockNumber=0...11
+
+
+
+
+    // ----------------------------------------------------------------------------------------------------------
+    // --------------------------------------------- PRINTER ----------------------------------------------------
+    // ----------------------------------------------------------------------------------------------------------
+
+    // read printer condition and settings
+
+    uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const override;
+        // retval: status byte
+            // byte 0 = 0: prnter OK,  >0: error
+            // bit0: paper low  1: no paper    2: temperature error
+            // 3: head open     4: paper jam in cutter
+            // 6: no response   7: bad response from printer
+        // and return struct "Tprn_hw_state"
+
+    bool prn_isUpAndReady(void) const override;
+        // true: printer is powered, serial is ok, no error, printer is connected and resonding
+
+    void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const override;
+
+
+    // send Commands to printer:
+
+    void prn_sendText(QByteArray *buf) const override;
+        // up to 1280 bytes
+
+    void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const override;
+        // send three byte through to printer, see printers manual
+
+    void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const override;
+        // send four byte through to printer, see printers manual
+
+
+    void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const override;
+        // send 5 byte: byte 0,1: speed  5...250 mm/s
+        //              byte2: density   0....(25)....50
+        //              byte3: alignment    'l', 'c', 'r' = left, center, right
+        //              byte4: orientation  0, 90, 180    = 0°, 90°, 180° rotation (by now not supported!)
+        // not batched! don't use twice within 100ms
+
+    void prn_movePaper(uint8_t wayInMm, uint8_t direction) const override;
+        //direction: 1=forward 2=backward
+        //
+    void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const override;
+        // font = kind of font 5...11 (0..22)
+        // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge
+        // width:  0...4   0=1x  1=2x   2=4x (huge!)  3=8x 4=16x (3,4 make no sense)
+        // heigth: 0...7 = 1x...8x  only 0,1,2,(3) make sense
+
+    void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const override;
+        // bold: 0/1
+        // invers: 0/1
+        // underlined: 0/1
+
+    void prn_cut(uint8_t kindof) const override;
+        // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut)
+
+    void prn_newLine(uint8_t nrOfLines) const override;
+
+    void prn_printCompleteFontTable(void) const override;
+
+
+    void prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const override;
+        // kind of barcode: 0=Code39   1=Code128   2=EAN13    3= 2/5interleaved    4=UPC-A   5=EAN8
+        // withText:    print readable text below
+        // offset: move by pixel from left border
+        // rotation
+        // dataLeng in byte
+
+    void prn_sendQRdata(QByteArray *buf) const override;
+        // maximal 150 alphanummeric bytes
+
+    void prn_printQRcode(void) const override;
+        // QRcode may have 1...150 alphanummeric data, must be transfered in advance
+
+
+    void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const override;
+        // nrOfLogo: 1..4 in flash  5...8 in Ram
+        // offset: in mm form left border
+
+
+
+    // .........................................................
+    // Parking Ticket (print-out document) designer TD
+    // .........................................................
+
+    // Predefine document Layout (e.g. parking ticket) in advance and stroe it for quick and easy use
+    // in opposite to the above "single" commands you need only one or a few commands at vending time.
+    // Stored text is just send to printer once the printing command is issued
+    // stored commands within the text are interpreted and executed right at the place (in ticket) they are
+    // example: start bold, <text in bold>, stop bold
+    // Predefinition of up to 16 ticket Layouts is possible, 0...1280 byte each
+    // Number 0..15, al keept non-volatile
+    // up to 8 dynamic values can be defined in the template ("print val3 here") and will be sent with printing command
+    // example: print current time at this point (the time of printing not the storage time!!)
+
+    void pri_startTicketDesign(void) const override;
+        // start for every new printer document, reseting collecting buffer
+
+    // all further functions write/append text, numbers and command to the ticket-buffer, up to 1278 bytes allowed
+    // return val of the appending functions: true=ok false=too long, buffer full
+
+    int pri_TD_getCurrentSize(void) const override;
+        // retval: 0...1278
+
+    bool pri_TD_addText(QByteArray text) const override;
+        // example: pri_TD_addText("Hello") const override;
+        // example: pri_TD_addText(tempStr) const override;
+        // retval: true=ok false=too long, buffer full
+
+    bool pri_TD_addValue(int val) const override;
+        // +/- 0...2^(31)
+
+    bool pri_TD_addNewLine(void) const override;
+
+    bool pri_TD_addSign(char sign) const override;
+        // example: '.'   ' '   0x20 'W' '$'
+
+    bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const override;
+        // always add 8 byte to the ticket layout:  ESC & group & attribute & parameter1...5
+        /* complete list of possible commands:
+            group 50 : paper
+                attribute 10 :  move forward
+                      p1: wayInMm p2: direction
+                attribute 11 : cut
+                      p1: kind of, 1=full 2=partial, 3=eject
+                attribute 12 : new line(s)
+                      p1: nr of lines 1...100
+
+            group 51 : fonts
+                attribute 10 : kind of font     see description above
+                      p1: 0...8
+                attribute 11 : font size
+                      p1: 6...20
+                attribute 12 : font width
+                      p1: 0...4
+                attribute 13 : font heigth
+                      p1: 0...7
+                attribute 14 : switch bold print on/off
+                      p1: 0=off  1=on
+                attribute 15 : switch invers print on/off
+                      p1: 0=off  1=on
+                attribute 16 : switch underlined print on/off
+                      p1: 0=off  1=on
+
+            group 52 : print graphics
+                attribute 10 : print barcode with dynamic data 6 and 7
+                      p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above
+                attribute 11 : print QRcode with preset data
+
+                attribute 12 : print Logo
+                     p1=nrOfLogo, p2=offset
+
+            group 53 : print dynamics
+                attribute 10 :
+                        p1: 1...8 = print dynData 0..7 at this place
+
+    */
+
+    char prn_clearDocument(uint8_t documentNumber) const override;
+        // clear memory buffer for ONE document
+        // function takes a second! don't send right before "store doc"
+
+    bool prn_store_Document(uint8_t documentNumber ) const override;
+
+        // send the predefined Layout (generated with above TD functions) to DeviceController to save
+        // documentNumber=0...15
+        // maximal 1280 bytes each
+        // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc)
+        // 0x1B=start of embedded command (next 7bytes = command)
+
+    // with a print command a set of 8 dynamic strings can be sent
+    // the place in the ticket layout is predefined (already in DC memory)
+    // the dynamics are first calculated at printing time
+
+    bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const override;
+
+
+
+
+
+    // ----------------------------------------------------------------------------------------------------------
+    // --------------------------------------------- MDB Bus ----------------------------------------------------
+    // ----------------------------------------------------------------------------------------------------------
+
+    //void mdb_switchPower(bool on) const override;            defined above
+    //void mdb_switchWake(bool WAKEACTIVE) const override;     defined above
+//    bool mdb_WakeINisActive(void) const override;
+//    bool mdb_testIsmdbTxDon(void) const override;
+//    bool mdb_isMdbPowerOn(void) const override;
+//    void request_MDB_Status() const override;
+//    void request_MDB_lastResponse() const override;
+
+
+    void mdb_sendBusReset(void) const override;
+
+    void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const override;
+        // send one bus command directly over mdb bus, refer to mdb manual for commands
+        // this command is not needed in normal operation, just for new or special things
+
+    void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const override;
+        // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
+        // same as mdb_sendCommand, just with data
+
+    bool mdb_busIsReadyToWork() const override;
+
+    bool mdb_deviceVoltageOK() const override;
+
+    bool mdb_busVoltageOk() const override;
+
+    uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
+                                      uint8_t *responseLength, uint8_t *responseBuffer) const override;
+        // fromDevice: device nr from which data was requested 0,1,2,3
+        // lastRequest: sent mdb command
+        // responseLength: nr of payload data (after mdb-ack) 0...34
+        // responseBuffer holds payload data (answer from mdb device)
+        // return val: mdb result of this request: 1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
+
+
+
+
+
+    // ----------------------------------------------------------------------------------------------------------
+    // ---------------------------------- Electronic Coin Validator EMP -----------------------------------------
+    // ----------------------------------------------------------------------------------------------------------
+
+
+    void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const override;
+        // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
+        // tokenChannel 0...31: if this signal comes from emp then a token was inserted
+        // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
+
+    void emp_pollingOnOff(uint8_t on) const override;
+
+    void emp_startCoinAcceptance(void) const override;
+
+    void emp_stopCoinAcceptance(void) const override;
+
+    void emp_getAllParameters(struct T_emp *emp) const override;
+        // see struct in hwapi.h
+        // usage example:
+        //      hwapi   *HWaccess const override;
+        //      HWaccess = new hwapi() const override;
+        //      struct T_emp   myEmp const override;
+        //      HWaccess->emp_getAllParameters(&myEmp) const override;
+        //          readval=myEmp.pollingRunning const override;
+
+    uint8_t emp_chkIfCoinInserted(void) const override;
+        // retval: 0...16 coins left in FIFO
+
+    void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const override;
+        // with every call ONE coin is taken out of FIFO and pointer decremented
+        // valid: should be 1
+        // signal: comes right from coin checker, 0...15 (0=first programmed coin type) 0xFF=no signal
+        // error: was reported from EMP as dynamic signal right after coin insertion (instead of
+        //          coin signal), example: 3=unknown coin  4=coin is blocked by host.  0xFF=no error
+        // value: of the coin. Depends on parameter "coinDenomination" in function "emp_sendSettings"
+        //          if coinDenomination[coin 0..15] = 0 then the value programmed in coin checker is taken
+        //          if coinDenomination > 0 then this value is taken.
+        //          Useful in case of two currencies (adapt to local currency) or for token.
+
+    // function gives more details as "emp getLastCoin()" but "emp getLastCoin()" is easier to use
+
+    // alternativ to emp_getNewCoinRecord( ):
+    uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const override;
+        // retval: 0: NO coin stored  1: valid coin  2: got wrong coin or coin denied
+        // value: if retval1: value of the coin if reval=2: error number
+        //          0xFF means NO error or NO signal  (as 0 is a valid error/signal)
+        // signal: channel nr reported from checker 0...15
+
+
+
+
+
+// neu, 25.3.23
+
+    void bl_rebootDC(void) const override;
+
+    void bl_startBL(void) const override;
+    bool bl_checkBL(void) const override;
+    bool bl_isUp(void) const override;
+        // return true is bl is up and running
+        // also initializes "sendFile"
+
+    void bl_sendAddress(uint16_t blockNumber) const override;
+        // send start address, nr of 64byte-block, start with 0
+        // will be sent only for folling block-numbers:
+        // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
+
+    uint8_t bl_wasSendingAddOK(void) const override;
+    // return val: 0: no response by now  1:error  10: OK
+
+    void bl_openBinary(void) const override;
+
+    void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const override;
+    // send 64 byte from bin file
+
+    void bl_sendLastBlock(void) const override;
+
+    uint8_t bl_wasSendingDataOK(void) const override;
+    // return val: 0: no response by now  1:error  10: OK
+
+    void bl_stopBL(void) const override;
+
+
+    // Bootlader, not used or obsolete
+    //bool bl_isDiagAvailable(void) const override;
+    //QString dc_getDiagText(void) const override;
+    //void bl_startSending(void) const override;
+    //void bl_sendFile(void) const override;
+
+
+
+// neu, ab 6.4.23
+// bereits vorhanden, nochmal getestet/verbessert:
+    // void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const override;
+    // void alarm_switchSiren(bool on) const override;
+
+    // void mif_readerOn(bool on) const override;
+    // bool mif_cardIsAttached(void) const override;
+
+    // void shut_move(bool open) const override;
+    // void esc_moveFlaps(uint8_t flap ) const override;
+        // 0: close both  1: open take-flap   2: open return
+    // void shut_openOnce(void) const override;
+        // and close automatic after shutter time
+    // void shut_openForCoin(bool start) const override;
+        // open flap if coin is attached
+        // once process is started it runs until stop command
+    // void shut_sendOpeningTime(uint16_t timeIn_ms ) const override;
+        // after this time without retrigger the flap is closed
+    // void esc_takeMoney(void) const override;
+        // and close automatically after escrow time (1s)
+    // void esc_returnMoney(void) const override;
+        // and close automatically after escrow time (1s)
+
+    // void prn_switchPower(bool on) const override;
+    // void prn_sendText(QByteArray *buf) const override;
+        // up to 1280 bytes
+
+    // uint8_t rtc_setDateTime(void) const override;
+            // send system time
+
+    //void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
+    //                        uint8_t kindOfMifareReader, uint8_t suppressSleep,
+    //                        uint8_t kindOfModem,        uint8_t kindOfCredit        ) const override;
+
+    //void sendMachineID(uint16_t customerNr, uint16_t machineNr,
+    //                          uint16_t borough, uint16_t zone,
+    //                          uint16_t alias,   char *location) const override;
+
+    /*
+    uint8_t emp_getInsertedCoinSignal(void) const override;
+        // can be called one time after each coin
+        // emp_chkIfCoinInserted() must be called before!
+
+    uint16_t emp_getInsertedCoinValue(void) const override;
+        // can be called one time after each coin
+        // emp_chkIfCoinInserted() must be called before!
+
+    uint8_t emp_getCoinError(void) const override;
+        // can be called one time after each coin
+        // emp_chkIfCoinInserted() must be called before!
+    */
+
+    bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const override;
+        // return true if successful. could fail if more the 8 commands are waiting
+
+    bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const override;
+
+    bool sys_runCompleteTest(void) const override;
+        // warning: lasts 20s in one pace
+
+    bool sys_ready4sending(void) const override;
+    // return true if a Json-file can be sent
+
+    bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const override;
+        // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
+        //      nrOfTemplate=1...32 if kindOfFile==6
+        //      content = content of the Json file, max 800byte ascii signs
+        // file is 0-terminated!
+        // return false if sending is not possible, wait a second
+
+    bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const override;
+    // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string
+    //            like:     char prn_dynPrnVal[8][8];
+    // return true if sending, false if cmd-stack is full
+
+    bool prn_printTemplate(uint8_t nrOftemplate) const override;
+        // print one of the templates loaded by Json prior
+        // nr = 1..32
+        // return true if sending, false if cmd-stack is full
+
+    void log_getHoldAccountNumbers(uint32_t *accNr ) const override;
+        // returns all acc nrs of the backuped vault records
+        // use: uint32_t backupedAccNumbers[8]
+
+    bool log_selectVaultRecord(uint16_t accountNr ) const override;
+        // return true if sending, false if cmd-stack is full
+
+//request, isAvailable
+    void log_getVaultRecord(struct T_vaultRecord *retVR) const override;
+        // which was selected by: log_selectVaultRecord()
+        // to be forwarded to Ismas
+
+    bool prn_printAccountReceipt(void) const override;
+        // return true if sending to DC OK, false if cmd-stack is full
+
+    bool prn_printTestTicket(void) const override;
+        // return true if sending to DC OK, false if cmd-stack is full
+
+    bool cash_startPayment(uint16_t amount) const override;
+
+    bool cash_cancelPayment(void) const override;
+        // and return coins
+
+    bool cash_stopPayment(void) const override;
+        // and keep coins in escrow
+
+    uint32_t getInsertedAmount(void) const override;
+
+    uint16_t getLastInsertedCoin(void) const override;
+
+    bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const override;
+        // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64
+
+
+    // after ticket/goods issue:
+    bool vend_success(void) const override;
+        // conclude payment process, encash all inserted coins to vault. Printing was successful
+        // if possible return change
+
+    bool vend_failed(void) const override;
+        // conclude payment process and return all inserted coins
+
+
+
+
+
+    uint8_t mif_getCardType(QString cardholder) const override;
+        // return 1,2,3,4 = upper, lower access card, printer test, coin test
+        // cardholder: 7byte Name-String
+
+    uint64_t sys_getWakeSource(void) const override;
+        // retval: 6 bytes, bit coded, 1=event keeps DC awake
+
+    //void sys_getDeviceConditions(struct T_moduleCondition *devCond) const override;
+    void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const override;
+
+    //void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const override;
+    void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const override;
+
+
+
+
+
+private:
+    void sub_storeSendingText(QByteArray *buf) const;
+
+
+
+
+
+
+};
+
+
+#endif
+
+
+
+/*
+    // Coin checker and changer mdb4.2 / section 5
+    // Level 2 Commands  (predefined device msg acc. mdb manual and auto-poll)
+    uint8_t mdb_coin_startPolling(bool on) const override;    // send ether one command (from list below)
+                                               // or a poll command in the proper polling grid (e.g. every 100ms)
+    uint8_t mdb_coin_reset() const override;
+    uint8_t mdb_coin_setup() const override;
+    uint8_t mdb_coin_tubestatus() const override;
+    uint8_t mdb_coin_pollManually(void) const override;
+    uint8_t mdb_coin_type(uint16_t coinEnable, uint16_t dispenseEnable) const override;
+    uint8_t mdb_coin_dispense(uint8_t disp) const override;
+    uint8_t mdb_coin_expansion(uint8_t subCmd, uint8_t send[32]) const override;
+    uint8_t mdb_coin_getResponse(void) const override;
+            // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
+    uint8_t mdb_coin_getDataLen(void) const override;
+        // return nr of byte received from any mdb device
+    uint8_t mdb_coin_getData(uint8_t *mdb_data, uint8_t maxBufferSize) const override;
+
+
+
+    // Bill validator       // section 6
+    uint8_t mdb_bill_startPolling(bool on) const override;
+    uint8_t mdb_bill_reset() const override;
+    uint8_t mdb_bill_setup() const override;
+    uint8_t mdb_bill_security(uint16_t secLevel) const override;
+    uint8_t mdb_bill_pollManually(void) const override;
+    uint8_t mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable) const override;
+    uint8_t mdb_bill_escrow(uint8_t action) const override;
+    uint16_t mdb_bill_stacker(void) const override;
+    uint8_t mdb_bill_expansion(uint8_t subCmd, uint8_t send[32]) const override;
+    uint8_t mdb_bill_gotPollResponse(void) const override;
+            // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
+    uint8_t mdb_bill_getDataLen(void) const override;
+    uint8_t mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize) const override;
+
+
+
+    // Level 3 Commands - all cash devices are used together and automatically
+    // -->easiest way to use
+
+    // setting up payment:
+    uint8_t cash_getAcceptance(struct Tcash_state *cash_state) const override;
+        // return device specific parameters, (e.g. which tubes are installed)
+        // to be requested before/after payment
+    uint8_t cash_setMaxReturn(uint32_t amount) const override;         // Security Limit
+    uint8_t cash_setMaxAcceptance(uint32_t amount) const override;     // can pay up to this amount
+        // example: set to 12€ (=max price step), then the 3rd 5€ bill would be kept in escrow
+        // or with coins: max. insertable = 13,95€ (11,95€ is still <12€, plus a 2€-coin)
+    uint8_t cash_setCoinsToBeAccepted(uint16_t coinVal[2][16]) const override;
+        // up to 16 coins per currency in one or two currencies
+        // [0]=first currency, e.g. Huf  [1]=2nd, like euros
+    uint8_t cash_setBillsToBeAccepted(uint32_t billVal[2][16]) const override;
+    uint8_t cash_setOpeningTime(uint16_t opentime_100ms) const override;       // coin slot is opening/closing automatically
+    uint8_t cash_setWaitForLastCoinTime(uint16_t lastCoinTime_100ms) const override;
+        // while this time coin/bill aceptance is still active after "disable payment" command
+    uint8_t cash_getAllsettings(struct TcashSettings cashSettings) const override;
+        // return all above set own parameters
+
+    // starting payment
+    uint8_t cash_powerUp(bool on) const override;              // power up/down devices (bill takes up to 3s)
+    uint8_t cash_enablePayment(bool start) const override;     // start/stop accepting bills and coins
+
+    // running payment
+    bool    gotNewCoinBill(void) const override;                    // true on every insertion, only once
+    uint8_t cash_getInserted(struct Tcash_pay *payment_state) const override;
+
+    // finishing payment
+    uint8_t cash_coinEscrowTake(void) const override;
+    uint8_t cash_coinEscrowReturn(void) const override;
+    uint8_t cash_return(uint32_t amount) const override;
+*/
+
+
+/*
+    uint8_t cc_setCondition(uint16_t chgCmd) const override;      // e.g. change to state registered, sleep, open, off....
+    uint16_t cc_getCondition(void) const override;                // e.g. now socket open
+    bool    cc_sendBufferFree(void) const override;               // sending allowed (before writing) and sending finished (after writing)
+    uint8_t cc_sendDataBlk(uint16_t len, uint8_t *buf) const override;
+    void    cc_wantReadData(uint16_t nrOfData) const override;                        // start reading
+    uint16_t cc_gotData(void) const override;                             // return nr of received bytes
+    uint8_t cc_loadDataBlk(uint16_t len, uint8_t *buf) const override;
+    uint8_t cc_getWorkFlow(void) const override;
+        // off, activated, gotStart_wait4card, wait4pin, gotPin, callingBank, CardAccepted.....
+    uint8_t cc_setupSerial(struct TserialParams serialParameter) const override;
+    uint8_t cc_getCurrentSerialSettings(struct TserialParams *serialParameter) const override;
+*/
+
+
+/*
+
+struct TcashSettings
+{
+    uint32_t MaxReturnAmount const override;
+    uint32_t MaxAcceptAmount const override;
+    uint32_t CoinsAcceptedCur[2][16] const override;
+    uint32_t BillsAcceptedCur[2][16] const override;
+    uint32_t availableReturnAmount const override;
+
+} const override;
+
+
+struct Tcc_hw_state
+{
+    bool powerRdBk const override;     // prn pwr is on
+    bool rsSwOk const override;        // serial switch (printer or modem) is set to CreditCard (iUC)
+    bool rsDrvOk const override;       // RS232 converter for PTU, Printer and Modem in on
+    uint8_t HwState const override;    // idle, off, on, ready
+    bool gotAnswer const override;     // cable OK?
+    uint8_t moduleType const override;
+    uint8_t protocolType const override;
+
+} const override;
+
+
+*/
+
+
+/*
+    // not yet implemented
+    uint8_t mod_power(bool on) const override;
+    uint8_t mod_getHwState(struct Tmod_hw_state *mod_hw_state) const override;
+    uint8_t mod_setCondition(uint16_t chgCmd) const override;      // e.g. change to state registered, sleep, open, off....
+    uint16_t mod_getCondition(void) const override;                // e.g. now socket open
+    bool    mod_sendBufferFree(void) const override;               // sending allowed (before writing) and sending finished (after writing)
+    uint8_t mod_sendDataBlk(uint16_t len, uint8_t *buf) const override;
+    void    mod_wantReadData(uint16_t nrOfData) const override;                        // start reading
+    uint16_t mod_gotData(void) const override;                             // return nr of received bytes
+    uint8_t mod_loadDataBlk(uint16_t len, uint8_t *buf) const override;
+    uint8_t mod_setupSerial(struct TserialParams serialParameter) const override;
+    uint8_t mod_getCurrentSerialSettings(struct TserialParams *serialParameter) const override;
+
+    // Credit Card Terminal:
+    uint8_t cc_power(bool on) const override;
+    uint8_t cc_getHwState(struct Tcc_hw_state *cc_hw_state) const override;
+
+*/
+
diff --git a/DCPlugin/include/interfaces.h b/DCPlugin/include/interfaces.h
index 3aac4f0..0358f16 100644
--- a/DCPlugin/include/interfaces.h
+++ b/DCPlugin/include/interfaces.h
@@ -310,12 +310,12 @@ public:
                                           QVector<int> templateIdx,
                                           QVector<QString> fnames,
                                           QString br,
-                                          QString serial) const = 0;
+                                          QString serial = QString()) const = 0;
 
     virtual bool dc_printTemplate(enum FileTypeJson type,
                                   QVector<int> templateIdx,
                                   QString br,
-                                  QString serial) const = 0;
+                                  QString serial = QString()) const = 0;
 
     virtual void dc_autoRequest(bool on)  const =0;
         // on = true:  select that all READ-Requests are sent automatically 
diff --git a/DCPlugin/src/hwapi.cpp b/DCPlugin/src/hwapi.cpp
index d6f454c..ca0ad84 100644
--- a/DCPlugin/src/hwapi.cpp
+++ b/DCPlugin/src/hwapi.cpp
@@ -1,3539 +1,3551 @@
-/*
- * API to the PSA2020 Hardware
- * All data come in from device controller via serial interface and will be stored
- * PI is updated every 100ms
- * This api uses stored data and returns them in the following functions
- * created: Q1/2020 TS until Q2/21
- *
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <thread>
-#include <algorithm>
-
-#include <QFileInfo>
-
-#include "tslib.h"
-#include "hwapi.h"
-
-#include "sendWRcmd.h"
-#include "controlBus.h"
-#include "storeINdata.h"
-#include "dcBL.h"
-#include <QDebug>
-#include <../plugins/interfaces.h>
-
-
-static const QMap<QString, int> baudrateMap = {
-  {"1200"   ,   0}, {"9600"   ,   1}, {"19200"  ,   2}, {"38400"  ,   3},
-  {"57600"  ,   4}, {"115200" ,   5}
-};
-
-hwapi::hwapi(QWidget *parent) : QObject(parent)
-{
-    // constructor
-    //epi_resetAllDOs();
-    //PI_INI();
-    sendWRcmd_INI();
-
-    myDatif = new T_datif();
-}
-
-
-
-void hwapi::sub_storeSendingText(QByteArray *buf) const
-{
-
-    char local[70], copie[1350];    // 64byte more then max buffer size!
-    int LL, nn, len, maxruns=20;
-
-    epi_resetPrinterStack();
-    // make a copy of the incoming byteArray as the byteArray can not be moved (crash!)
-    tslib_strclr(copie, 0, 1350);
-    LL=buf->length();
-    for (nn=0; nn<LL; nn++)
-    {
-        copie[nn]=buf->at(nn);
-    }
-
-    tslib_strclr(local, 0, 66);
-    LL=buf->length();
-    if (LL>1280)
-    {
-        qDebug()<<"reducing text size from " << LL << " to 1280 bytes";
-        LL=1280;   // Limit size
-    } else
-        qDebug()<<"\n printing text with " << LL << " bytes: ";
-
-    do
-    {
-        len=tslib_getMinimum(LL, 64);
-        tslib_strclr(local, 0, 66);
-        for (nn=0; nn<len; nn++)
-        {
-            local[nn]=copie[nn];
-        }
-        local[64]=0;
-
-        // delete already printed part of big buffer
-        if (LL<=64)
-        {
-            // last block
-            local[LL]=10;
-            // new line = cmd to printer: "print, even if line is not filled"
-            LL=0;       // print complete
-        } else
-        {
-            LL-=64;
-            for (nn=0; nn<LL; nn++)
-            {
-                copie[nn]=copie[nn+64];
-            }
-            // pad remain with 0 (last but one block)
-            for (nn=LL; nn<64; nn++)
-            {
-                copie[nn]=0;
-            }
-        }
-
-
-        epi_storePrnText(local, uint8_t(len));    // no need to care for max PI size
-            // stores 64byte in PI with every call, maximal 20 calls (1280 byte)
-
-    } while(--maxruns>0 && LL>0);
-
-}
-
-
-// ------------------------------------------------------------------------------
-// Level 0 commands, interface
-// open, close, change serial interface
-// actually not neccessary as it is opened automatically on program start
-// start automatic READ requests
-// ------------------------------------------------------------------------------
-
-bool hwapi::dc_openSerial(int BaudNr, QString BaudStr,
-                          QString ComName, uint8_t connect) const {
-    // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
-    // BaudStr: for exapmle "19200"
-    // ComName: for example "COM48"
-    // connect: 0, 1
-    //qDebug() << "~~>LIB" << "dc_openSerial called... " ;
-
-    epi_setSerial(BaudNr, BaudStr, ComName, connect);
-
-    // Actions: open serial port with parameters
-    for (int i = 0; i < 10; ++i) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        if (dc_isPortOpen()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool hwapi::dc_closeSerial(void) const {
-    epi_closeSerial();
-    for (int i = 0; i < 10; ++i) {
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        if (!dc_isPortOpen()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool hwapi::dc_isPortOpen(void) const {
-    if (myDatif) {
-        T_prot* prot = myDatif->getProt();
-        if (prot) {
-            T_com *com = prot->getSerialPort();
-            if (com) {
-                return com->isPortOpen();
-            }
-        }
-    }
-    return false;
-    //return epi_isSerialPortOpen();
-}
-
-void hwapi::dc_autoRequest(bool on) const
-{
-    // automatically request ALL digital and analog sensors, get time/date, get status information
-    if (on)
-        epi_startEmmision(1);
-    else
-        epi_startEmmision(0);
-}
-
-/******************************************************************************/
-//
-//              LEVEL 2: Help-functions for hwapi::dc_updateDC.
-//
-/******************************************************************************/
-hwapi::DownloadResult hwapi::sendStatus(int ret) const {
-    switch (ret) {                      // return values of dc are:
-    case 0:                             // 0: no answer by now
-        return DownloadResult::NOP;     // 1: error
-    case 10:                            // 10: success
-        return DownloadResult::OK;
-    default:;
-    }
-    return DownloadResult::ERROR;
-}
-
-hwapi::DownloadResult hwapi::sendNextAddress(int bNum) const {
-    // sends address only if blockNumber is one of 0, 1024, 2048, 3072, 4096
-    int noAnswerCount = 0;
-    int errorCount = 0;
-    if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) {
-        qDebug() << "addr-block" << bNum << "...";
-        while (noAnswerCount <= 250) {
-            bl_sendAddress(bNum);
-            std::this_thread::sleep_for(std::chrono::milliseconds(100));
-            DownloadResult const res = sendStatus(bl_wasSendingAddOK());
-            if (res != DownloadResult::NOP) {
-                if (res == DownloadResult::ERROR) {
-                    if (++errorCount >= 10) {
-                        qCritical() << "addr-block" << bNum << "...FAILED";
-                        return res;
-                    }
-                } else { // res == DownloadResult::OK
-                    qInfo() << "addr-block" << bNum << "...OK";
-                    return res;
-                }
-            } else {
-                noAnswerCount += 1; // no answer by now
-            }
-        }
-        // wait max. about 3 seconds
-        return DownloadResult::TIMEOUT;
-    }
-    // blockNumber is not one of 0, 1024, 2048, 3072, 4096 -> do nothing
-    return DownloadResult::NOP;
-}
-
-hwinf::DownloadResult hwapi::sendNextDataBlock(QByteArray const &binary,
-                                               int bNum) const {
-    uint8_t local[66];
-    int const bAddr = bNum * 64;
-    int noAnswerCount = 0;
-    int errorCount = 0;
-
-    memcpy(local, binary.constData() + bAddr, 64);
-    local[64] = local[65] = 0x00;
-
-    qDebug() << "data for addr" << bAddr << "...";
-
-    while (noAnswerCount <= 250) {
-        bl_sendDataBlock(64, local);
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
-        DownloadResult const res = sendStatus(bl_wasSendingDataOK());
-        if (res != DownloadResult::NOP) {
-            if (res == DownloadResult::ERROR) {
-                if (++errorCount >= 10) {
-                    qCritical() << "data for addr" << bAddr << "...FAILED";
-                    return res;
-                }
-            } else {
-                qInfo() << "data for addr" << bAddr << "...OK";
-                return res;
-            }
-        } else {
-            noAnswerCount += 1; // no answer by now
-        }
-    }
-    // wait max. about 3 seconds
-    return DownloadResult::TIMEOUT;
-}
-
-hwinf::DownloadResult hwapi::dc_downloadBinary(QByteArray const &b) const {
-    int const nBlocks = (((b.size())%64)==0) ? (b.size()/64) : (b.size()/64)+1;
-
-    qInfo() << "total number of bytes to send to dc" << b.size();
-    qInfo() << "total number of blocks to send to dc" << nBlocks;
-
-    int bNum = 0;
-    DownloadResult res = DownloadResult::OK;
-    while (res != DownloadResult::ERROR &&  bNum < nBlocks) {
-        if ((res = sendNextAddress(bNum)) != DownloadResult::ERROR) {
-            if ((res = sendNextDataBlock(b, bNum)) != DownloadResult::ERROR) {
-                bNum += 1;
-            }
-        }
-    }
-    if (res != DownloadResult::ERROR) {
-        bl_sendLastBlock();
-    }
-    return res;
-}
-
-bool hwapi::startBootloader() const {
-    qDebug() << "starting bootloader...";
-    int nTry = 5;
-    while (--nTry >= 0) {
-        bl_startBL();
-        std::this_thread::sleep_for(std::chrono::milliseconds(500));
-        if (bl_isUp()) {
-            qInfo() << "starting bootloader...OK";
-            std::this_thread::sleep_for(std::chrono::milliseconds(500));
-            return true;
-        }
-    }
-    qCritical() << "starting bootloader...FAILED";
-    return false;
-}
-
-bool hwapi::stopBootloader() const {
-    qDebug() << "stopping bootloader...";
-    int nTry = 5;
-    while (--nTry >= 0) {
-        bl_stopBL();
-        std::this_thread::sleep_for(std::chrono::milliseconds(500));
-        if (!bl_isUp()) {
-            qInfo() << "stopping bootloader...OK";
-            return true;
-        }
-    }
-    qCritical() << "stopping bootloader...FAILED";
-    return false;
-}
-
-// br is a index into a table, used for historical reasons.
-bool hwapi::openSerial(int br, QString baudrate, QString comPort) const {
-    qDebug() << "opening serial" << br << baudrate << comPort << "...";
-    if (dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect
-        qInfo() << "opening serial" << br << baudrate << comPort << "...OK";
-        return true;
-    }
-    qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED";
-    return false;
-}
-
-bool hwapi::closeSerial(QString comPort) const {
-    qDebug() << "closing serial" << comPort << "...";
-    if (dc_closeSerial()) {
-        qInfo() << "closing serial" << comPort << "...OK";
-        return true;
-    } else {
-        qCritical() << "closing serial" << comPort << "...FAILED";
-    }
-    return false;
-}
-
-bool hwapi::resetDeviceController() const {
-    qDebug() << "resetting device controller...";
-    if (stopBootloader()) { // first stop a (maybe) running bootloader
-        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
-        dc_OrderToReset();
-        // wait maximally 3 seconds, before starting bootloader
-        std::this_thread::sleep_for(std::chrono::milliseconds(1500));
-        qInfo() << "resetting device controller...OK";
-        return true;
-    }
-    return false;
-}
-
-QByteArray hwapi::loadBinaryDCFile(QString filename) const {
-    qDebug() << "loading dc binary" << filename << "...";
-
-    QFile file(filename); // closed in destructor call
-    if (!file.exists()) {
-        qCritical() << file.fileName() << "does not exist";
-        return QByteArray();
-    }
-    if (!file.open(QIODevice::ReadOnly)) {
-        qCritical() << "cannot open file" << file.fileName();
-        return QByteArray();
-    }
-    qInfo() << "loading dc binary" << filename << "...OK";
-    return file.readAll();
-}
-
-bool hwapi::downloadBinaryToDC(QString const &bFile) const {
-    qDebug() << "sending" << bFile << "to dc...";
-    QByteArray const dcBinary = loadBinaryDCFile(bFile);
-    if (dcBinary.size() > 0) {
-        if (dc_downloadBinary(dcBinary) != DownloadResult::OK) {
-            qCritical() << "sending" << bFile << "to dc...FAILED";
-            return false;
-        } else {
-            qInfo() << "sending" << bFile << "to dc...OK";
-        }
-    } else {
-        qCritical() << "sending" << bFile << "to dc...FAILED";
-        qCritical() << "loading binary" << bFile << "FAILED";
-        return false;
-    }
-    return true;
-}
-
-/******************************************************************************/
-//
-//                        LEVEL 3: hwapi::dc_updateDC.
-//
-/******************************************************************************/
-bool hwapi::dc_updateDC(QString bFile, QString br, QString serial) const {
-    if (!baudrateMap.contains(br)) { // sanity check
-        qCritical() << "passed wrong baudrate" << br;
-        return false;
-    }
-
-    qDebug() << "updating dc: " << bFile << br << serial << "...";
-
-    if (!openSerial(baudrateMap.value(br), br, serial)) {
-        return false;
-    }
-    if (!resetDeviceController()) {
-        closeSerial(serial);
-        return false;
-    }
-    if (!startBootloader()) {
-        closeSerial(serial);
-        return false;
-    }
-    if (!downloadBinaryToDC(bFile)) {
-        stopBootloader();
-        closeSerial(serial);
-        qCritical() << "updating dc: " << bFile << br << serial << "...FAILED";
-        return false;
-    }
-
-    qInfo() << "updating dc: " << bFile << br << serial << "...OK";
-
-    stopBootloader();
-    closeSerial(serial);
-    return true;
-}
-
-/******************************************************************************/
-//
-//                   LEVEL 3: hwapi::dc_updatePrinterTemplate
-//
-/******************************************************************************/
-bool hwapi::dc_updatePrinterTemplate(enum FileTypeJson type,
-                                     QVector<int> templatesIdx,
-                                     QVector<QString> fnames,
-                                     QString br,
-                                     QString serial) const {
-    // sanity checks
-    if (!baudrateMap.contains(br)) {
-        qCritical() << "passed wrong baudrate" << br;
-        return false;
-    }
-    if (templatesIdx.size() != fnames.size()) {
-        qCritical() << "list sizes must be equal" << br;
-        return false;
-    }
-    if (!std::all_of(templatesIdx.cbegin(), templatesIdx.cend(),
-                    [](int i) { return i >= 1 && i <= 32; })) {
-        qCritical() << "wrong template indices";
-        return false;
-    }
-    if (type != FileTypeJson::PRINTER) {
-        qCritical() << "wrong file type" << (uint8_t)type;
-        return false;
-    }
-
-    qDebug() << "updating: " << fnames << br << serial << "...";
-
-    if (!openSerial(baudrateMap.value(br), br, serial)) {
-        return false;
-    }
-
-    int nTry = 50;
-    while (!sys_ready4sending()) { // wait max. 5 seconds
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        if (--nTry <= 0) {
-            qCritical() << "sys not ready for sending";
-            closeSerial(serial);
-            return false;
-        }
-    }
-
-    bool ret = true;
-    for (int i = 0; i < fnames.size(); ++i) {
-        QFile file(fnames[i]);
-        if (file.exists() && file.open(QIODevice::ReadOnly)) {
-            QByteArray ba = file.readAll();
-            if (ba.size() <= 800) { // max. size is 800 bytes
-                if (sys_sendJsonFileToDc((uint8_t)(type),
-                                          templatesIdx[i],
-                                          (uint8_t *)ba.data())) {
-                    std::this_thread::sleep_for(std::chrono::seconds(1));
-                    qInfo() << "sent file" << fnames[i] << "to dc";
-                }
-            }
-        } else {
-            qCritical() << fnames[i] << "!!! does not exist!!!";
-            ret = false;
-            continue;
-        }
-    }
-    closeSerial(serial);
-    return ret;
-}
-
-bool hwapi::dc_printTemplate(enum FileTypeJson type,
-                             QVector<int> templateIdx,
-                             QString br,
-                             QString serial) const {
-    // sanity checks
-    if (!baudrateMap.contains(br)) {
-        qCritical() << "passed wrong baudrate" << br;
-        return false;
-    }
-    if (!std::all_of(templateIdx.cbegin(), templateIdx.cend(),
-                    [](int i) { return i >= 1 && i <= 32; })) {
-        qCritical() << "wrong template indices";
-        return false;
-    }
-    if (type != FileTypeJson::PRINTER) {
-        qCritical() << "wrong file type" << (uint8_t)type;
-        return false;
-    }
-
-    qDebug() << "printing: " << templateIdx << br << serial << "...";
-
-    if (!openSerial(baudrateMap.value(br), br, serial)) {
-        return false;
-    }
-
-    int nTry = 50;
-    while (!sys_ready4sending()) { // wait max. 5 seconds
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        if (--nTry <= 0) {
-            qCritical() << "sys not ready for sending";
-            closeSerial(serial);
-            return false;
-        }
-    }
-
-    bool ret = true;
-    for (int i = 0; i < templateIdx.size(); ++i) {
-        if (prn_printTemplate(templateIdx[i])) {
-            qDebug() << "printing template" << templateIdx[i];
-            std::this_thread::sleep_for(std::chrono::seconds(3));
-        } else {
-            ret = false;
-            continue;
-        }
-    }
-    closeSerial(serial);
-    return ret;
-
-}
-
-// ------------------------------------------------------------------------------
-// Level 1, control device-controller (functions of µC)
-// check serial connection to deviceController
-// read response from DC2 (input data)
-// some test function for serial communication
-// also Bootloader is here
-// ------------------------------------------------------------------------------
-
-void hwapi::dc_requTestResponse() const
-{
-    sendWRcmd_setSendCommand0(SENDDIRCMD_TestSerial);
-}
-
-bool hwapi::dc_readAnswTestResponse() const
-{
-    return epi_getResult_serialTestOK();
-}
-
-uint8_t hwapi::dc_isRequestDone(void) const
-{
-    // retval:  0: request is still in progress
-    //          1: answer from DC2 was OK
-    //          2: wrong answer from DC2
-    return epi_getResultOfLastRequest();
-}
-
-uint16_t hwapi::dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const
-{
-    // get data back in *pl, max 64 byte, can be used for diagnosis
-    // 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
-
-    return epi_getLastPayLoad( plBufSiz,  payLoad);
-
-}
-
-void hwapi::dc_setWakeFrequency(uint8_t period) const
-{
-    // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
-    // change wake signal period to 1...64s
-    sendWRcmd_setSendCommand4(SENDDIRCMD_setWakeFrequ, period,0,0,0);
-}
-
-void hwapi::dc_OrderToReset(void) const
-{
-    uint8_t len, buf[160];
-
-    len=dcBL_restartDC(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-    //sendWRcmd_setSendCommand0(SENDDIRCMD_MakeReset);
-    // not needed, sendWRcmd_setSendBlock160() starts sending as well...
-}
-
-QString hwapi::dc_getSerialState(void) const
-{
-// geht
-    return epi_getTxt4comStateLine();
-}
-
-void hwapi::dc_clrSerialStateText(void) const
-{
-    epi_clrTxt4comStateLine();
-}
-
-
-
-void hwapi::bl_sendDataDirectly(uint8_t length, uint8_t *buf) const
-{
-    // send without protocol frame, needed for the DC bootloader
-    sendWRcmd_setSendBlock160(length, buf);
-
-}
-
-uint8_t hwapi::getRawRecLength(void) const
-{
-    return epi_getRawRecLength();
-}
-
-uint8_t hwapi::getRawReceivedData(uint8_t *receivedData) const
-{
-    return epi_getRawReceivedData(receivedData);
-}
-
-
-
-
-QString hwapi::dc_getSerialParams(void) const
-{
-    return epi_getSlaveParamSTR();
-}
-
-QString hwapi::dc_getHWversion(void) const
-{
-    return epi_loadGenerals(0);
-}
-
-QString hwapi::dc_getSWversion(void) const
-{
-    return epi_loadGenerals(1);
-}
-
-QString hwapi::dc_getState(void) const
-{
-    return epi_loadGenerals(2);
-}
-
-
-// ------------------------------------------------------------------------------
-// Level 2  DC2-onboard devices
-//          WR: set time
-//          RD. get time, get measure, get test results
-// ------------------------------------------------------------------------------
-
-// get UID, get time/date   test results   memory,  RTC  analog values
-
-// ----------------------------------------------------------------------------------------------------------
-// Date and Time
-// ----------------------------------------------------------------------------------------------------------
-
-uint8_t hwapi::rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const
-{
-//    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);
-    uint8_t H, M, S;
-    uint16_t unused16;
-    uint32_t unused32;
-
-    epi_getTime(&H, &M, &S);
-    rtc_DateTime->rtc_hour=H;
-    rtc_DateTime->rtc_min=M;
-    rtc_DateTime->rtc_sec=S;
-
-    epi_getDate(&H, &M, &S);
-    rtc_DateTime->rtc_year=H;
-    rtc_DateTime->rtc_month=M;
-    rtc_DateTime->rtc_dayOfMonth=S;
-
-    epi_getToday(&H, &unused16, &unused32);
-    rtc_DateTime->rtc_dayOfWeek=H;
-    return 0;
-}
-
-uint8_t hwapi::rtc_setDateTime(void) const
-{
-    sendWRcmd_setSendCommand0(SENDDIRCMD_setTime);
-    return 0;
-}
-
-
-void hwapi::rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const
-{
-    epi_getTime(hh, mm, ss);
-}
-
-void hwapi::rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const
-{
-    epi_getDate(yy, mm, dd);
-}
-
-uint8_t hwapi::rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const
-{
-    // dow=day of week, 1=monday...7
-    // minOfToday: 0=midnight...1439= 23:59
-    // secOfToday: 0=midnight...86399= 23:59:59
-
-    epi_getToday(dow, minOfToday, secOfToday);
-    return 0;
-}
-
-bool hwapi::rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const
-{
-    return epi_isLeapYear(lastLeapYear, NextLeapYear);
-}
-
-
-bool hwapi::rtc_isLeapYear(void) const
-{
-    return epi_isLeapYear();
-}
-
-void hwapi::rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const
-{
-    epi_getSpecialWeekTimeDate(DayOfWeek, HoursOfWeek, MinutesOfWeek);
-}
-
-void hwapi::rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const
-{
-    epi_getSpecialMonthTimeDate(DayOfMonth, HoursOfMonth, MinutesOfMonth);
-}
-
-void hwapi::rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const
-{
-    epi_getSpecialYearTimeDate(DayOfYear, HoursOfYear, MinutesOfYear);
-}
-
-
-QString hwapi::rtc_getTimStr() const
-{
-    uint8_t hh,  mm,  ss, buf[20], nn;
-    QString qbuf;
-
-    qbuf.clear();
-    for (nn=0; nn<20; nn++) buf[nn]=0;
-    epi_getTime(&hh, &mm, &ss);
-    GetTimeString(hh, mm, ss, HourSys24h, MITSEK, buf); // about 12byte long
-    for (nn=0; nn<20; nn++) qbuf[nn]=buf[nn];
-
-    return qbuf;
-}
-
-QString hwapi::rtc_getDatStr() const
-{
-    uint8_t day,  month,  year, buf[20], nn;
-    QString qbuf;
-
-    qbuf.clear();
-    for (nn=0; nn<20; nn++) buf[nn]=0;
-    epi_getDate(&year, &month, &day);
-    GetDateString(day, month, 0x20, year, DateFormatDeutsch, 0, buf);
-    for (nn=0; nn<20; nn++)
-        qbuf[nn]=buf[nn];
-
-    return qbuf;
-}
-
-QString hwapi::rtc_getTimDatStr() const
-{
-    // style: 0: hh:mm    1: hh:mm:ss
-    QString qbuf;
-
-    qbuf.clear();
-    qbuf.append(rtc_getTimStr());
-    qbuf.append("   ");
-    qbuf.append(rtc_getDatStr());
-    return qbuf;
-}
-
-
-
-
-
-// UID
-void hwapi::dc_getUID8byte(uint8_t *buf8byteUid) const
-{
-    epi_getUIDdec(buf8byteUid);
-}
-
-QString hwapi::dc_getUIDstr() const
-{
-    return epi_getUIDstr();
-}
-
-uint64_t hwapi::dc_getUIDnumber(void) const
-{
-    uint64_t retval=0;
-    uint8_t buf8byteUid[12], nn;
-
-    epi_getUIDdec(buf8byteUid);
-    for (nn=8; nn>0; nn--)
-    {
-        retval+=buf8byteUid[nn-1];
-        retval<<=8;     // *256
-    }
-    return retval;
-}
-
-
-
-uint32_t hwapi::dc_getTemperature(void) const
-{
-    //
-    return epi_loadMeasureValue(MEASCHAN_TEMPERATURE);
-}
-
-QString hwapi::dc_getTemperaturStr(void) const
-{
-    return epi_getSlaveTemperatureStr();
-}
-
-
-uint32_t hwapi::dc_getVoltage(void) const
-{
-    // in mV, e.g. 12300 = 12,3V
-    return epi_loadMeasureValue(MEASCHAN_VOLTAGE);
-}
-
-QString hwapi::dc_getVoltagStr(void) const
-{
-    return epi_getSlaveVoltageStr();
-}
-
-bool hwapi::dc_mainFuseIsOk(void) const
-{
-    uint32_t ulong=epi_loadMeasureValue(MEASCHAN_VOLTAGE); // in mV, e.g. 12300 = 12,3V
-    if (ulong>3000)
-        return true;
-    return false;
-}
-
-// ------------------------------------------------------------------------------
-// Level 3: digital outputs and simple switching of connected devices
-//          simple processes like flashing a led or open flap for 1s
-// ------------------------------------------------------------------------------
-
-// Locks:
-uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const
-{
-    // dir 0=off 1=up 2=down
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEUP_LOCK ,dir,0,0,0);
-    return 0;
-}
-
-uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const
-{
-    // dir 0=off 1=up 2=down
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEDN_LOCK ,dir,0,0,0);
-    return 0;
-}
-
-void hwapi::lock_switchVaultDoor(void) const
-{
-
-    sendWRcmd_setSendCommand0(SENDDIR_OPENVAULT);
-}
-
-void hwapi::coin_switchRejectMotor(uint8_t dir) const
-{
-
-    sendWRcmd_setSendCommand4(SENDDIR_REJMOT_ON, dir, 0,0,0);
-}
-
-void hwapi::coin_rejectCoins(void) const
-{
-
-    sendWRcmd_setSendCommand0(SENDDIR_REJMOT_RUN);
-}
-
-
-void hwapi::led_switchLedService(uint8_t on) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDINSIDE, on, 0, 0, 0);
-}
-
-void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDTICKET, on, ton, tof, 0);
-}
-
-void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDPAD, on, ton, tof, 0);
-}
-
-void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDSTART, on, ton, tof, 0);
-}
-
-void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDCOIN, on, ton, tof, 0);
-}
-
-void hwapi::fan_switchFan(bool on) const
-{
-    //return epi_storeDOsToSend(DOBYTE3, FAN_ON, on);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_FAN, on, 0, 0, 0);
-}
-
-void hwapi::alarm_switchSiren(bool on) const
-{
-    //return epi_storeDOsToSend(DOBYTE4, LAERM, on);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_LAERM, on, 0, 0, 0);
-}
-
-void hwapi::bar_OpenBarrier(bool open) const
-{
-    //return epi_storeDOsToSend(DOBYTE4, REL1, open);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_REL1, open, 0, 0, 0);
-}
-
-void hwapi::ptu_switchWake(bool WAKEACTIVE) const
-{
-    //return epi_storeDOsToSend(DOBYTE1, CTS_PTU, WAKEACTIVE);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_WAKEPTU, WAKEACTIVE,0,0,0);
-}
-
-// AUX-IO's or barcode reader
-void hwapi::aux_power(bool on) const
-{
-//    return epi_storeDOsToSend(DOBYTE2, BARC_POW_ON, on);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXPWR, on,0,0,0);
-}
-
-void hwapi::aux_setUsage(uint8_t PinDirection) const
-{
-    // bit 0= Aux1    bit5=Aux6  1=output  0=input with pullup
-
-    //    return epi_storeDOsToSend(DOBYTE6, nr, PinDirection);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXDDR, PinDirection,0,0,0);
-}
-
-void hwapi::aux_setOutputs(uint8_t PinIsHigh) const
-{
-    // PinIsHigh bit 0..5 =Aux1...6  1=output high  0=set output low
-
-    //return epi_storeDOsToSend(DOBYTE5, nr, PinIsHigh);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXOUT, PinIsHigh,0,0,0);
-}
-
-void hwapi::lock_switchContactPower(bool on) const
-{
-    //epi_storeDOsToSend(DOBYTE2, U_SW_ON, on);
-    sendWRcmd_setSendCommand4(SENDDIRCMD_UCONTACT_ON, on, 0,0,0);
-}
-
-void hwapi::prn_switchPower(bool on) const
-{
-    // also switches and enables serial driver
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN2_SWONOFF, on,0,0,0);
-    indat_storePrinterPower(on);
-    // PRINTER-ON/OFF zusätzlich statisch abspeichern
-    //       Status-request soll nur gesendet werden wenn der Drucker ein ist
-    //       Status-Abfrage (hier in HWapi) gibt 0 zurück wenn power-off
-    // dito mit allen anderen Geräten!
-
-    // pi ---> storeINdata.cpp  speichert diese statische Info (printer on/off) UND
-    // auch alles rückgelesene
-
-}
-
-
-void hwapi::mif_readerOn(bool on) const
-{
-    // DC2 also switches and enables serial driver
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0);
-}
-
-void hwapi::mif_creatAtbCard(uint8_t cardType) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, cardType, 0,0,0);
-}
-
-
-void hwapi::mod_switchPower(bool on) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_SWONOFF, on,0,0,0);
-}
-
-void hwapi::mod_switchWake(bool WAKEACTIVE) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_WAKE, WAKEACTIVE,0,0,0);
-}
-
-void hwapi::mdb_switchPower(bool on) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_POWER, on,0,0,0);   
-}
-
-void hwapi::mdb_switchWake(bool WAKEACTIVE) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_WAKE, WAKEACTIVE,0,0,0);
-}
-
-void hwapi::credit_switchPower(bool on) const
-{    
-    sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_ON, on,0,0,0);
-}
-
-void hwapi::credit_switchWake(bool WAKEACTIVE) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_WAKE, WAKEACTIVE,0,0,0);
-}
-
-void hwapi::shut_move(bool open) const
-{
-    // true:open  false:close
-    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_MOV, open, 0,0,0);
-}
-
-void hwapi::esc_moveFlaps(uint8_t flap ) const
-{
-    // 0: close both  1: open take-flap   2: open return
-    sendWRcmd_setSendCommand4(SENDDIRCMD_ESCRO_MOV, flap, 0,0,0);
-}
-
-
-// ------------------------------------------------------------------------------
-// Level 3: digital inputs of connected devices
-// ------------------------------------------------------------------------------
-
-
-
-uint8_t hwapi::door_getSwitches(void) const
-{
-    // retval         // bit0: upper door  1: low door  2:vault door
-    uint8_t ret;
-
-    ret= epi_getDI_doorSwitches();
-        // bit0: upper door  1: low door  2:vault door
-    ret &= 0x08;
-    return ret;
-}
-
-bool    hwapi::door_isUpperDoorOpen(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_doorSwitches();
-        // bit0: upper door  1: low door  2:vault door
-    if (ret &  1)
-        return true;
-    return false;
-}
-
-bool    hwapi::door_isLowerDoorOpen(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_doorSwitches();
-        // bit0: upper door  1: low door  2:vault door
-    if (ret &  2)
-        return true;
-    return false;
-}
-
-bool    hwapi::vault_isVaultDoorOpen(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_doorSwitches();
-        // bit0: upper door  1: low door  2:vault door
-    if (ret &  4)
-        return true;
-    return false;
-}
-
-
-uint8_t hwapi::vault_getSwitches(void) const
-{
-    // retval bit0: cash box,  bit 1: bill box
-    uint8_t ret;
-
-    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
-    ret&=0x03;
-    return ret;
-}
-
-bool hwapi::vault_isCoinVaultIn(void) const
-{
-    uint8_t ret;
-
-    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
-    if (ret & 1)
-        return true;
-    return false;
-}
-
-bool hwapi::vault_isBillVaultIn(void) const
-{
-    uint8_t ret;
-
-    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
-    if (ret & 2)
-        return true;
-    return false;
-}
-
-
-
-uint8_t hwapi::door_getLocks(void) const
-{
-    // retval bit0: upper lever is up
-    //        bit1: upper lever is down
-    //        bit2: lower lever is up
-    //        bit3: lower lever is down
-
-    uint8_t ret;
-
-    ret= epi_getDI_lockSwitches();
-        // retval: bit 0: upper lockbar up   bit1: upper lockbar is down
-        //         bit 2: lower lockbar up   bit1: lower lockbar is down
-    ret&=0x0F;
-    return ret;
-}
-
-bool hwapi::door_upperDoorIsLocked(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_lockSwitches();
-    if (ret & 2)
-        return true;
-    return false;
-}
-
-bool hwapi::door_upperDoorIsUnlocked(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_lockSwitches();
-    if (ret & 1)
-        return true;
-    return false;
-}
-
-bool hwapi::door_lowerDoorIsLocked(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_lockSwitches();
-    if (ret & 8)
-        return true;
-    return false;
-}
-
-bool hwapi::door_lowerDoorIsUnlocked(void) const
-{
-    uint8_t ret;
-
-    ret= epi_getDI_lockSwitches();
-    if (ret & 4)
-        return true;
-    return false;
-}
-
-
-
-bool    hwapi::bar_optoIn1isOn(void) const
-{
-    uint8_t ret=epi_getDI_optos();
-        // bit0: opto in 1    1: opto in 2
-    if (ret & 1)
-        return true;
-    return false;
-}
-
-bool    hwapi::bar_optoIn2isOn(void) const
-{
-    uint8_t ret=epi_getDI_optos();
-        // bit0: opto in 1    1: opto in 2
-    if (ret & 2)
-        return true;
-    return false;
-}
-
-
-uint8_t hwapi::aux_getAuxInputs(void) const
-{
-    // retval: bit0=Aux1....Bit5=Aux6
-    //          0: input low  1:input high
-
-    uint8_t ret=epi_getDI_auxIn();
-    // bit0: auxin 1  ...  5: auxin 6
-    ret &=0x3F;
-    return ret;
-}
-
-bool hwapi::ptu_WakeINisActive(void) const
-{
-    return epi_getDI_ptuWake();
-}
-
-bool hwapi::mdb_WakeINisActive(void) const
-{
-    return epi_getDI_mdbWake();
-}
-
-bool hwapi::prn_readyINisActive(void) const
-{
-    return epi_getDI_prnReady();
-}
-
-bool hwapi::coid_isAttached(void) const
-{
-    return epi_getDI_CoinAttach();
-}
-
-bool hwapi::coin_escrowIsOpen(void) const
-{
-    return epi_getDI_CoinEscrow();
-}
-
-bool hwapi::mif_cardIsAttached(void) const
-{
-    return epi_getDI_mifareCardTapped();
-}
-
-//bool hwapi::mod_WakeINisActive(void)
-//{
-//    return epi_getDI_modemWake();
-//}
-
-
-
-bool hwapi::door_isContactPowerOn(void) const
-{
-    return  epi_getDI_contactPwr();
-}
-
-bool hwapi::mif_isMifarePowerOn(void) const
-{
-    bool mo=indat_isMifareOn();
-    bool mi=epi_getDI_mifarePwr();
-    if (mo && mi)
-        return true;
-    return false;
-}
-
-bool hwapi::mdb_testIsmdbTxDon(void) const
-{
-    return  epi_getDI_mdbTxd();
-}
-
-bool hwapi::aux_isAuxPowerOn(void) const
-{
-    return  epi_getDI_auxPwr();
-}
-
-bool hwapi::mod_isGsmPowerOn(void) const
-{
-    return  epi_getDI_gsmPwr();
-}
-
-bool hwapi::cred_isCreditPowerOn(void) const
-{
-    return  epi_getDI_creditPwr();
-}
-
-bool hwapi::prn_isPrinterPowerOn(void) const
-{
-    return  epi_getDI_printerPwr();
-}
-
-uint8_t hwapi::prn_PrnFuseIsOk(void) const
-{
-    //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off
-    if (!epi_getDO_printerPwr())
-        return 2;       // unknown as printer power is off
-    if (epi_getDI_printerPwr())
-        return 1;       // printer voltage is OK
-    return 0;       // fuse blown
-}
-
-bool hwapi::mdb_isMdbPowerOn(void) const
-{
-    return  epi_getDI_mdbPwr();
-}
-
-
-bool hwapi::cash_getRejectMotorHomePos(void) const
-{
-    return epi_getDI_rejectMotor_homepos();
-}
-
-uint8_t hwapi::cash_getLowPaperSensor(void) const
-{
-    // 0: Sensor sees paper 1: no paper 99: off
-    return  epi_getDI_npe_sensor();
-
-}
-
-// ------------------------------------------------------------------------------
-// Level1,2,3     RD request commands
-// ------------------------------------------------------------------------------
-
-// the following requests can be sent manually
-//   or automatically in background by:   void hwapi::dc_autoRequest(bool on)
-//   in other words:
-//   if automatic-reading is on then there's no need to send any of these commands!
-
-
-void hwapi::request_DC2serialConfig() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_SERCONF);
-}
-
-void hwapi::request_DC2_HWversion() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_HWversion);
-}
-
-void hwapi::request_DC2_SWversion() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_SWversion);
-}
-
-void hwapi::request_DC2_condition() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_CONDITION);
-}
-
-void hwapi::request_DC2_UID() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_UID);
-}
-
-void hwapi::request_DC2_TimeAndDate() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_TIME);
-}
-
-void hwapi::request_DC2_analogues() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_ANALOGS);
-}
-
-void hwapi::request_DC2_digitalInputs() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_DIG_INPUTS);
-}
-
-void hwapi::request_DC2_digitalOutputs() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_DIG_OUTPUTS);
-}
-
-// ------------------------------------------------------------------------------
-// the folowing device state requests are deployed only if device is powered up:
-
-void hwapi::request_PrinterHwState() const
-{
-
-    sendWRcmd_setSendCommand0(SEND_REQU_PRN_STATE);
-}
-
-void hwapi::request_PrinterCurrentFonts() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_PRN_FONTS);
-}
-
-void hwapi::request_PrinterStateComplete() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_PRN_ALL);
-}
-
-
-
-
-
-void hwapi::request_MifareReaderState() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
-}
-
-void hwapi::request_MifareCardType() const
-{
-    //uint8_t blkAdr=0;
-    //sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, blkAdr,0,0,0);
-    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
-}
-
-void hwapi::request_MifareAtbType() const
-{
-    //sendWRcmd_setSendCommand0(SEND_REQU_MIF_ATB_TYPE);
-    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
-
-}
-
-void hwapi::request_MifareID() const
-{
-    uint8_t sequenceNumber=0;
-    sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, sequenceNumber,0,0,0); // 1st data = card sequence =blk nr (0...15)
-}
-
-void hwapi::request_MifareData(uint8_t dataBlockNumber) const
-{   
-    if (dataBlockNumber<12)     // 1k cards return 12 data blocks, 4k cards would return 54 data blocks (not implemented)
-        sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15)
-}
-
-
-
-void hwapi::request_MDB_Status() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETSTAT);
-}
-
-//void hwapi::request_MDB_wakeInLine() const
-//{
-//    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK);
-//}
-
-void hwapi::request_MDB_lastResponse() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETRESP);
-}
-
-void hwapi::request_EMP_allParameters() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETALL);
-}
-
-void hwapi::request_EMP_lastCoin() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETCOIN);
-
-}
-
-
-
-// ------------------------------------------------------------------------------
-// Level 3: readback digital outputs of connected devices
-//          these functions are not needed for normal operation
-//          but can be used to test and verify conditions
-
-//          There are two options:
-//              1) the important things like power-outputs and wake lines are
-//              measured at DC2-terminals (after transistors) and come as input to DC-board
-//              2) others like Leds are read from µC-pins by DC-board
-// ------------------------------------------------------------------------------
-
-bool hwapi::test_getDO_mdbRXtst(void) const
-{
-    return  epi_getDO_mdbRxTestOut();
-}
-
-uint8_t hwapi::lock_getDO_motors(void) const
-{
-    // bit0: upper lock forward    bit 1 backward
-    // bit2: lower lock forward    bit 3 backward
-
-    return epi_getDO_motorOuts();
-}
-
-uint8_t hwapi::test_serialState(void) const
-{
-    // test on-board signals for the serials
-    // serial drv on/off, Serial mux1, Serial mux2
-
-    uint8_t ret=epi_getDO_serialSwitch();
-        // serial drv on/off, Serial mux1, Serial mux2
-    ret &=0x07;
-    return ret;
-}
-
-bool hwapi::test_serialIsOn(void) const
-{
-    return epi_getDO_serialDriverIsOn();
-}
-
-bool hwapi::test_serialMux1isSetToPrinter(void) const
-{
-    return epi_getDO_serialMux1isSetToPrinter();
-    // mux1 off: serial is switched to printer
-}
-
-bool hwapi::test_serialMux1isSetToModem(void) const
-{
-    return  epi_getDO_serialMux1isSetToModem();
-    // mux1 on: serial is switched to modem
-}
-
-bool hwapi::test_serialMux2isSetToCredit(void) const
-{
-    return epi_getDO_serialMux2isSetToCredit();
-    // mux2 off: serial is switched to credit card terminal
-}
-
-bool hwapi::test_serialMux2isSetToMifare(void) const
-{
-    return epi_getDO_serialMux2isSetToMifare();
-    // mux2 on: serial is switched to mifare reader
-}
-
-bool hwapi::led_coinIsOn(void) const
-{
-    return epi_getDO_led_coin();
-}
-
-bool hwapi::led_frontIsOn(void) const
-{
-    return epi_getDO_led_front();
-}
-
-bool hwapi::led_ticketIsOn(void) const
-{
-    return epi_getDO_led_ticket();
-}
-
-bool hwapi::led_pinIsOn(void) const
-{
-    return epi_getDO_led_pin();
-}
-
-bool hwapi::led_StartIsOn(void) const
-{
-    return epi_getDO_led_start();
-}
-
-bool hwapi::led_insideIsOn(void) const
-{
-    return epi_getDO_led_inside();
-}
-
-bool hwapi::fan_isOn(void) const
-{
-    return epi_getDO_fan();
-}
-
-bool hwapi::siren_isOn(void) const
-{
-    return epi_getDO_sirene();
-}
-
-bool hwapi::bar_relayIsOn(void) const
-{
-    return epi_getDO_relay();
-}
-
-bool hwapi::ptu_WakeOutIsOn(void) const
-{
-    return epi_getDO_ptuWake();
-}
-
-bool hwapi::aux_powerIsOn(void) const
-{
-    return epi_getDO_auxPower();
-}
-
-
-bool hwapi::coin_shutterIsOpen(void) const
-{
-    return epi_getDO_coinShutterOpen();
-}
-
-bool hwapi::coin_shutterTestOutput(void) const
-{
-    return epi_getDO_coinShutterTest();
-}
-
-uint8_t hwapi::coin_escrowFlapOpened(void) const
-{
-    // retval: 1:return flap is open   2:take flap is open    0:closed
-
-    return epi_getDO_coinEscrow();
-}
-
-
-
-
-
-
-
-
-// ------------------------------------------------------------------------------
-// Level4   devices are operated by DC
-//          processes with more then one devices
-//          timer controlled or long term processes
-// ------------------------------------------------------------------------------
-
-
-
-
-void hwapi::sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker,
-                               uint8_t kindOfMifareReader, uint8_t suppressSleep,
-                               uint8_t kindOfModem, uint8_t kindOfCredit) const
-{
-    uint8_t buf[64];
-
-    tslib_strclr(buf,0,64);
-    buf[0]=kindOfPrinter;
-    buf[1]=kindOfCoinChecker;
-    buf[2]=kindOfMifareReader;
-    buf[3]=suppressSleep;
-    buf[4]=kindOfModem;
-    buf[5]=kindOfCredit;
-
-    epi_store64ByteSendData(6, buf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_DEVICE_PARA);
-
-
-}
-
-void hwapi::request_ReadbackDeviceSettings() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_DEVICE_PARA);
-}
-
-
-void hwapi::readback_DeviceSettings(uint8_t *length, uint8_t *data) const
-{
-
-    epi_restoreRbDeviceSettings(length, data);
-/*
-            buf66[0]=devPara.kindOfPrinter;
-            buf66[1]=devPara.kindOfCoinChecker;
-            buf66[2]=devPara.kindOfMifareReader;
-            buf66[3]=devPara.suppressSleepMode;
-            buf66[4]=devPara.kindOfModem;
-            buf66[5]=devPara.kindOfCreditcard;
-            buf66[6]=devPara.CoinEscrow;
-            buf66[7]=devPara.CoinRejectUnit;
-            buf66[8]=devPara.CoinShutter;
-            buf66[9]=devPara.BillAcceptor;
-            buf66[10]=devPara.usevaultLock;
-            buf66[11]=devPara.autoAlarm;
-            buf66[12]=devPara.autoOpen;
-            buf66[13]=devPara.printAccReceipt;
-            buf66[14]=devPara.printDoorReceipt;
-            buf66[15]=devPara.printTokenTicket;
-            uitmp=devPara.VaultFullWarnLevel;
-            buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
-            buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
-            uitmp=devPara.VaultFullErrorLevel;
-            buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
-            buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
-
-*/
-}
-
-// ....................................................................................
-
-void hwapi::sendMachineID(uint16_t customerNr, uint16_t machineNr,
-                          uint16_t borough, uint16_t zone,
-                          uint16_t alias,   char *location) const
-{
-    uint8_t buf[64];
-
-    tslib_strclr(buf,0,64);
-    buf[0]=uint2uchar(customerNr, LOWBYTE);
-    buf[1]=uint2uchar(customerNr, HIGHBYTE);
-    buf[2]=uint2uchar(machineNr, LOWBYTE);
-    buf[3]=uint2uchar(machineNr, HIGHBYTE);
-    buf[4]=uint2uchar(borough, LOWBYTE);
-    buf[5]=uint2uchar(borough, HIGHBYTE);
-    buf[6]=uint2uchar(zone, LOWBYTE);
-    buf[7]=uint2uchar(zone, HIGHBYTE);
-    buf[8]=uint2uchar(alias, LOWBYTE);
-    buf[9]=uint2uchar(alias, HIGHBYTE);
-    tslib_strcpy(location, &buf[10], 32);
-
-    epi_store64ByteSendData(42, buf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_MACHINE_ID);
-
-
-}
-
-void hwapi::request_ReadbackMachineID() const
-{
-    sendWRcmd_setSendCommand0(SEND_REQU_MACINE_ID);
-}
-
-
-void hwapi::readback_machineIDdata(uint8_t *length, uint8_t *data) const
-{
-    epi_restoreMachineIDsettings(length, data);
-/*
-            buf66[0]=swl_getOneByteFromUint(machPara.customerNumber, GETLOWBYT);
-            buf66[1]=swl_getOneByteFromUint(machPara.customerNumber, GETHIGHBYT);
-            buf66[2]=swl_getOneByteFromUint(machPara.machineNumber, GETLOWBYT);
-            buf66[3]=swl_getOneByteFromUint(machPara.machineNumber, GETHIGHBYT);
-            buf66[4]=swl_getOneByteFromUint(machPara.borough, GETLOWBYT);
-            buf66[5]=swl_getOneByteFromUint(machPara.borough, GETHIGHBYT);
-            buf66[6]=swl_getOneByteFromUint(machPara.zone, GETLOWBYT);
-            buf66[7]=swl_getOneByteFromUint(machPara.zone, GETHIGHBYT);
-            buf66[8]=swl_getOneByteFromUint(machPara.alias, GETLOWBYT);
-            buf66[9]=swl_getOneByteFromUint(machPara.alias, GETHIGHBYT);
-            for (pp=0; pp<32; pp++)
-                buf66[10+pp]=machPara.location[pp];
-            dc2prot_setReadData(42, buf66);
-
-*/
-}
-
-
-// ....................................................................................
-
-
-
-
-
-static uint16_t hwapi_shutterTime;
-
-// locks, 2.Level: (Motor stops automatical on end switch or by 5s timeout)
-uint8_t hwapi::lock_openUpperDoor(void) const
-{
-    //bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
-        // commands are defined in PIdefines.h
-    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 1, 0, 0, 0);
-        // paras:   dat2: 1=upper door lock   2=lower
-        //          dat1: 1=open              2=close
-    return 0;
-}
-
-
-uint8_t hwapi::lock_closeUpperDoor(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 2, 0, 0, 0);
-    return 0;
-}
-
-uint8_t hwapi::lock_openLowerDoor(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 1, 0, 0, 0);
-    return 0;
-}
-
-uint8_t hwapi::lock_closeLowerDoor(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 2, 0, 0, 0);
-    return 0;
-}
-
-void hwapi::shut_openOnce(void) const
-{
-    // and close automatic after shutter time
-    uint16_t zeit=hwapi_shutterTime;
-    zeit/=100;
-    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYTIME, uint8_t(zeit) ,0,0,0);
-
-}
-
-void hwapi::shut_openForCoin(bool start) const
-{
-    // start=true: start opening flap if coin is attached
-    // start=false: stop process
-
-    uint16_t zeit=hwapi_shutterTime;
-    zeit/=100;
-    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYCOIN, uint8_t(start), uint8_t(zeit),0,0);
-
-}
-
-void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const
-{
-    // after this time without retrigger the flap is closed
-    //sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_SENDTIME, timeIn100ms,0,0,0);
-    hwapi_shutterTime=timeIn_ms;
-
-}
-
-
-void hwapi::esc_takeMoney(void) const
-{
-    // and close automatically after escrow time (1s)
-    sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_TAKE);
-}
-
-void hwapi::esc_returnMoney(void) const
-{
-    // and close automatically after time
-    sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_GIVE);
-
-}
-
-
-
-
-
-
-
-// ----------------------------------------------------------------------------------------------------------
-// --------------------------------------------- MIFARE -----------------------------------------------------
-// ----------------------------------------------------------------------------------------------------------
-
-
-uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const
-{
-    // retval 0=OK 1=error host buffer too small
-
-    /* data description:
-
-    new fast version:
-    byte 0= still the same: 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: reader state 1=ok 0=nok
-    byte 2: card present (0,1)
-    byte 3: card selected (0)
-    byte 4: card type: 0...5
-    byte 5: card allowed (0=no  1=MifareClassic 1k or 4k)
-    byte 6: CardSize: 1 or 4 (kB)
-    byte 7: length of UID 4 or 7 (byte)
-    */
-
-    return epi_restoreMifState(buf, maxBufferSize);
-}
-
-/* OLD 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 "ATB25-1.8"
-16: 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
-*/
-
-bool hwapi::mif_readerIsOK(void) const
-{
-
-    uint8_t buf[40];    // old version had 40 bytes, new version only 8
-    uint8_t ret= epi_restoreMifState(buf, 40);
-    if (ret==0 && buf[0]>1 && buf[1]>0)
-            return 1;
-    return 0;   // error
-}
-
-bool hwapi::mif_cardAttached(void) const
-{
-
-    uint8_t buf[40];
-    uint8_t ret= epi_restoreMifState(buf, 40);
-    if (ret==0 && buf[0]>1 && buf[2]>0) // reader OK
-        if (buf[16]>0)
-            return 1;
-    return 0;   // error
-}
-
-uint8_t hwapi::mif_readResult(void) const
-{
-    // result: 0: unknown or still in progress
-    //         1: card read successful
-    //         2: reading error
-
-    uint8_t buf[40];
-    uint8_t ret= epi_restoreMifState(buf, 40);
-    // data read successful && Reader OK && card attached && ...
-    if (ret==0  && buf[1]>0 && buf[2]>0)
-    {
-//        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
-
-        if (buf[0]==1 || buf[0]==5 || buf[0]==6)
-            return 2;
-        if (buf[0]==4)
-            return 1;
-
-    }
-    return 0;   // error
-
-}
-
-
-QString hwapi::mif_cardUID(void) const
-{
-    QString myStr;
-
-    uint8_t buf[65], ret;
-
-    //uint8_t ret= epi_restoreMifState(buf, 40);
-    myStr.clear();
-/*
-    if (ret==0 && buf[0]==4 && buf[3]>0 && buf[16]>0 && buf[19]>0)
-    {
-        // UID in buf[22...29]
-        for (int ii=0;ii<8; ii++)
-        {
-
-            myStr+=QString::number(buf[ii+22],16);
-            myStr+=" ";     // make a gap between numbers
-        }
-    }
-*/
-
-    ret=epi_restoreMifData(0, buf, 64);
-    if (ret)
-        return myStr;   // return empty string on error
-    else
-    {
-        buf[8]=0;
-        //myStr.append(buf);
-        for (int ii=0;ii<8; ii++)
-        {
-
-            myStr+=QString::number(buf[ii],16); // 16: return in hex format
-            myStr+=" ";     // make a gap between numbers
-        }
-
-        return myStr;
-    }
-
-
-}
-
-
-uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const
-{
-    // blkNr=0...11    return buf[64]   maxBufferSize must be >=64
-
-    return epi_restoreMifData(blkNr, buf, maxBufferSize);
-    // blkNr=0...11    return buf[64]
-
-}
-
-QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const
-{
-    // with blockNumber=0...11
-    QString myStr;
-    uint8_t buf[66];
-
-    myStr.clear();
-    if (blockNumber>11)
-        return myStr;
-
-    epi_restoreMifData(blockNumber, buf, 66);
-
-    for (int ii=0; ii<64; ii++)
-    {
-        //myStr+=QString::number(buf[ii],10);     // decimals as ascii
-        myStr+=QString::number(buf[ii],16);     // hex numbers as ascii
-        myStr+=" ";     // make a gap between numbers
-    }
-    return myStr;
-}
-
-
-
-
-
-// ----------------------------------------------------------------------------------------------------------
-// --------------------------------------------- PRINTER ----------------------------------------------------
-// ----------------------------------------------------------------------------------------------------------
-
-// already above:
-// void hwapi::prn_switchPower(bool on)             0x2A01
-// bool hwapi::prn_readyINisActive(void)
-// bool hwapi::prn_isPrinterPowerOn(void)
-// void hwapi::request_PrinterHwState()             0x2A02
-// void hwapi::request_PrinterCurrentFonts()        0x2A12
-// void hwapi::request_PrinterStateComplete()   // =request_PrinterHwState + request_PrinterCurrentFonts
-
-uint8_t hwapi::prn_getHwState(struct Tprn_hw_state *prn_hw_state) const
-{
-    // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok?
-    //        printer on error or ok?
-    uint8_t prnHWstate[20];
-
-    epi_restorePrinterState(prnHWstate);
-        // byte 1...6 come right from printer, see printer manual
-        // byte 0 = all important infos:
-        // byte 0 = 0: prnter OK,  >0: error
-        // bit0: paper low  1: no paper    2: temperature error
-        // 3: head open     4: paper jam in cutter
-        // 6: no response   7: bad response from printer
-
-    prn_hw_state->powerRdBk = epi_getDI_printerPwr();
-    prn_hw_state->rsSwOk    = epi_getDO_serialMux1isSetToPrinter();   // mux1 off: serial is switched to printer
-    prn_hw_state->rsDrvOk   = epi_getDO_serialDriverIsOn();
-    prn_hw_state->ReadyLine = epi_getDI_prnReady();
-
-    if (prnHWstate[0]==0)
-        prn_hw_state->inIdle = true;    // no errors
-    else
-        prn_hw_state->inIdle = false;    // off or errors
-
-    if (prnHWstate[0] & 1)
-        prn_hw_state->paperNearEnd=true;
-    else
-        prn_hw_state->paperNearEnd = false;
-
-    if (prnHWstate[0] & 2)
-        prn_hw_state->noPaper=true;
-    else
-        prn_hw_state->noPaper = false;
-
-    if (prnHWstate[0] & 4)
-        prn_hw_state->ErrorTemp=true;
-    else
-        prn_hw_state->ErrorTemp = false;
-
-    if (prnHWstate[0] & 8)
-        prn_hw_state->HeadOpen=true;
-    else
-        prn_hw_state->HeadOpen = false;
-
-    if (prnHWstate[0] & 16)
-        prn_hw_state->cutterJam=true;
-    else
-        prn_hw_state->cutterJam = false;
-
-
-    if (prnHWstate[0] & 64)
-        prn_hw_state->noResponse=true;
-    else
-        prn_hw_state->noResponse = false;
-
-    if (prnHWstate[0] & 128)
-        prn_hw_state->badResponse=true;
-    else
-        prn_hw_state->badResponse = false;
-    return prnHWstate[0];
-
-}
-
-bool hwapi::prn_isUpAndReady(void) const
-{
-    struct Tprn_hw_state prnHwNow;
-
-    prn_getHwState(&prnHwNow);
-    if (prnHwNow.inIdle && prnHwNow.rsSwOk && prnHwNow.rsDrvOk && prnHwNow.powerRdBk )
-        return true;
-    return false;
-}
-
-void hwapi::prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const
-{
-    uint8_t prnFonts[22];
-
-    epi_restorePrinterFonts(&prnFonts[0]);
-    prn_fonts->currFont  = prnFonts[0];
-    prn_fonts->currSize  = prnFonts[1];
-    prn_fonts->currHeigth= prnFonts[2];
-    prn_fonts->currWidth = prnFonts[3];
-    prn_fonts->nowBold   = prnFonts[4];
-    prn_fonts->nowInvers = prnFonts[5];
-    prn_fonts->nowUnderlined= prnFonts[6];
-    prn_fonts->currDensity  = prnFonts[7];
-    prn_fonts->currSpeed    = prnFonts[8];
-    prn_fonts->nowAligned   = prnFonts[9];
-
-}
-
-
-void hwapi::prn_sendText(QByteArray *buf) const
-{
-    sub_storeSendingText(buf);
-    epi_storeUserOfSendingTextBuffer(1,0,0,0,0);  // 1=print text
-
-
-}
-
-
-void hwapi::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const
-{
-    // send three byte through to printer, see printers manual
-    sendWRcmd_setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3);
-}
-
-void hwapi::prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const
-{
-    // send four byte through to printer, see printers manual
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_ESC_CMD, para1, para2, para3, para4);
-}
-
-void hwapi::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const
-{
-    // send 5 byte: byte 0,1: speed  5...250 mm/s
-    //              byte2: density   0....(25)....50
-    //              byte3: alignment    'l', 'c', 'r' = left, center, right
-    //              byte4: orientation  0, 90, 180    = 0°, 90°, 180° rotation (by now not supported!)
-    // not batched! don't use twice within 100ms
-
-    uint8_t buf[10];
-    uint16_t uitmp;
-
-    uitmp=paperSpeed;
-    buf[0]=uint8_t(uitmp);
-    uitmp>>=8;
-    buf[1]=uint8_t(uitmp);
-    buf[2]=density;
-    buf[3]=alignment;
-    buf[4]=orientation;
-    buf[5]=0;
-    epi_store64ByteSendData(5, buf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_SETUP);
-}
-
-void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const
-{
-    //direction: 1=forward 2=backward
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_MOVE, wayInMm, direction, 0,0);
-}
-
-
-void hwapi::prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const
-{
-    // font = kind of font 0...8
-    // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge
-    // width:  0...4   0=1x  1=2x   2=4x (huge!)  3=8x 4=16x (3,4 make no sense)
-    // heigth: 0...7 = 1x...8x  only 0,1,2,(3) make sense
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETFONT, font, size, width, height);
-}
-
-
-void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETLETT, bold, invers, underlined, 0);
-}
-
-void hwapi::prn_cut(uint8_t kindof) const
-{
-    // kindof = 1: full cut  2: partial cut   3=eject (5xLF + full cut)
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CUT, kindof,0,0,0);
-}
-
-void hwapi::prn_newLine(uint8_t nrOfLines) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LF, nrOfLines, 0, 0, 0);
-}
-
-void hwapi::prn_printCompleteFontTable(void) const
-{
-    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_FONTTAB);
-}
-
-
-void hwapi::prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const
-{
-    uint8_t buf[66], nn;
-    //uint16_t uitmp;
-
-    if (dataLeng>58)
-        dataLeng=58;
-
-    buf[0]=kindOf;
-    buf[1]=withText;
-    buf[2]=offset;
-    buf[3]=rotation;
-    buf[4]=dataLeng;
-    // rest: Barcode-data:
-    for (nn=0; nn<dataLeng; nn++)
-        buf[5+nn]=data[nn];
-
-    epi_store64ByteSendData( (5+dataLeng), buf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_BC);
-}
-
-void hwapi::prn_sendQRdata(QByteArray *buf) const
-{
-    // maximal 150 alphanummeric bytes
-    sub_storeSendingText(buf);
-    epi_storeUserOfSendingTextBuffer(2,0,0,0,0);  // 2= print QRcode
-}
-
-void hwapi::prn_printQRcode(void) const
-{
-    // which was sent before
-    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_QR);
-}
-
-void hwapi::prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const
-{    
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LOGO_FL, nrOfLogo, offset, 0, 0);
-    pri_TD_addText("Hallo");
-}
-
-
-// .........................................................
-// Parking Ticket (print out) designer
-// .........................................................
-
-static QByteArray ticketTemplate;
-
-void hwapi::pri_startTicketDesign(void) const
-{
-    ticketTemplate.clear();
-
-}
-
-int hwapi::pri_TD_getCurrentSize(void) const
-{
-    return ticketTemplate.size();
-}
-
-bool hwapi::pri_TD_addText(QByteArray text) const
-{
-    if ((ticketTemplate.length() + text.length())>1278)
-        return false;
-    ticketTemplate.append(text);
-    qDebug()<<"\nText added "<<ticketTemplate;
-    return true;
-}
-
-bool hwapi::pri_TD_addValue(int val) const
-{
-    QString  tmpStr;
-    tmpStr.setNum(val,10);      // up to 12 chars
-    if (ticketTemplate.length()>1266)
-        return false;
-    ticketTemplate.append(tmpStr);
-    return true;
-}
-
-bool hwapi::pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const
-{
-    // always add 8 byte to the ticket layout:  ESC & group & attribute & parameter1...5
-    /* complete list of possible commands:
-        group 50 : paper
-            attribute 10 :  move forward
-                  p1: wayInMm p2: direction
-            attribute 11 : cut
-                  p1: kind of, 1=full 2=partial, 3=eject
-            attribute 12 : new line(s)
-                  p1: nr of lines 1...100
-
-        group 51 : fonts
-            attribute 10 : kind of font     see description above
-                  p1: possible: 0...22, expedient: 5...11
-            attribute 11 : font size
-                  p1: 6...20  12=normal   6=tiny
-            attribute 12 : font width
-                  p1: 0...4
-            attribute 13 : font heigth
-                  p1: 0...7
-            attribute 14 : switch bold print on/off
-                  p1: 0=off  1=on
-            attribute 15 : switch invers print on/off
-                  p1: 0=off  1=on
-            attribute 16 : switch underlined print on/off
-                  p1: 0=off  1=on
-
-        group 52 : print graphics
-            attribute 10 : print barcode with dynamic data 6 and 7
-                  p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above
-            attribute 11 : print QRcode with preset data
-
-            attribute 12 : print Logo
-                 p1=nrOfLogo, p2=offset
-
-        group 53 : print dynamics
-            attribute 10 : 1...8 = print dynData 0..7 at this place
-
-*/
-
-
-    char  tmpStr[10];
-
-    // command has always fixed length of 8 byte
-    if (ticketTemplate.length()>1270)
-        return false;
-    if (group<50 || group>59)
-        return false;
-    if (attribute<10 || attribute>30)
-        return false;
-
-    tmpStr[0]=0x1B;     // ESC
-    tmpStr[1]=group;
-    tmpStr[2]=attribute;
-    tmpStr[3]=p1;
-    tmpStr[4]=p2;
-    tmpStr[5]=p3;
-    tmpStr[6]=p4;
-    tmpStr[7]=p5;
-
-    ticketTemplate.append(tmpStr, 8);
-
-
-    qDebug()<<"\ncmd added "<<ticketTemplate;
-    return true;
-}
-
-bool hwapi::pri_TD_addNewLine(void) const
-{
-
-    if (ticketTemplate.length()>1277)
-        return false;
-    ticketTemplate.append("\n");
-    return true;
-}
-
-bool hwapi::pri_TD_addSign(char sign) const
-{
-    if (ticketTemplate.length()>1277)
-        return false;
-    ticketTemplate.append(sign);
-    return true;
-}
-
-
-char hwapi::prn_clearDocument(uint8_t documentNumber) const
-{
-    if (documentNumber>15)
-        return false;
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CLEARDOC, documentNumber, 0, 0, 0);
-    return true;
-}
-
-
-bool hwapi::prn_store_Document(uint8_t documentNumber ) const
-{
-    // send to DC
-    // documentNumber=0...15, stored in Eeprom
-    // maximal 1280 bytes each
-    // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc)
-    // 0x1B=start of embedded command (next 7bytes = command)
-
-    if (documentNumber>15)
-        return false;
-    sub_storeSendingText(&ticketTemplate);
-    epi_storeUserOfSendingTextBuffer(3,documentNumber,0,0,0);  // 3=store document
-    return true;
-}
-
-
-bool hwapi::prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const
-{
-    if (documentNumber>15)
-        return false;
-    epi_store64ByteSendData(64, &(dynTicketData->licensePlate[0]));
-    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_DOC, documentNumber, 0, 0, 0);
-    return true;
-}
-
-
-
-
-
-
-// ----------------------------------------------------------------------------------------------------------
-// ------------------------------------------- MDB Bus ------------------------------------------------------
-// ----------------------------------------------------------------------------------------------------------
-
-
-
-void hwapi::mdb_sendBusReset(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_RES, 0,0,0,0);
-
-}
-
-#define mdb_device_coinChk  0
-#define mdb_device_changer  1
-#define mdb_device_bill     2
-//#define mdb_device_credit   3   // obsolete
-
-
-void hwapi::mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_SENDCMD, toMdbDevice, mdbCommand, 0,0);
-
-}
-
-void hwapi::mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const
-{
-    // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
-    uint8_t myBuf[64], ii;
-
-    tslib_strclr(myBuf, 0, 64);
-    myBuf[0]=toMdbDevice;
-    myBuf[1]=mdbCommand;
-    if (nrOfData>34) nrOfData=34;
-    myBuf[2]=nrOfData;
-    for (ii=0; ii<nrOfData; ii++)
-        myBuf[ii+3]=dataBuffer[ii];
-    epi_store64ByteSendData(37, myBuf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_SNDMSG);
-}
-
-
-
-bool hwapi::mdb_busIsReadyToWork() const
-{
-    return epi_restoreMdbBusReady();
-}
-
-bool hwapi::mdb_deviceVoltageOK() const
-{
-    return epi_restoreMdbV12Ready();
-}
-
-bool hwapi::mdb_busVoltageOk() const
-{
-    return epi_restoreMdbV5Ready();
-}
-
-uint8_t hwapi::mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
-                                         uint8_t *responseLength, uint8_t *responseBuffer) const
-{
-    // fromDevice: device nr from which data was requested 0,1,2,3
-    // lastRequest: sent mdb command
-    // responseLength: nr of payload data (after mdb-ack) 0...34
-    // responseBuffer holds payload data (answer from mdb device)
-    // return val: mdb result of this request: 1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
-
-
-    uint8_t leng, ResData[64];
-
-    epi_restoreMdbResponse(&leng, ResData);
-    // 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: lastResult   1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
-    // DB3: nr of received (payload) data bytes (apart from ACK, can be 0....34)
-    // DB4...DB39: rec.data (payload)
-    *fromDevice=ResData[0];
-    *lastRequest=ResData[1];
-    *responseLength=ResData[3];
-    tslib_strcpy(&ResData[4], responseBuffer, ResData[3]);
-    return ResData[2];
-}
-
-
-
-// ----------------------------------------------------------------------------------------------------------
-// --------------------------------------------- Coin Checker -----------------------------------
-// ----------------------------------------------------------------------------------------------------------
-
-void hwapi::emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const
-{
-    // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
-    // tokenChannel 0...31: if this signal comes from emp then a token was inserted
-    // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
-
-    uint8_t myBuf[64], ii, pp;
-    uint16_t uitmp=coinAcceptance;
-
-    tslib_strclr(myBuf, 0, 64);
-    myBuf[0]=uint8_t (uitmp);
-    uitmp>>=8;
-    myBuf[1]=uint8_t (uitmp);
-    myBuf[2]=tokenChannel;
-    pp=3;
-    for (ii=0; ii<16; ii++)
-    {
-        uitmp=coinDenomination[ii];
-        myBuf[pp]=uint8_t(uitmp);
-        uitmp>>=8;
-        myBuf[pp+1]=uint8_t(uitmp);
-        pp+=2;
-    }
-
-    epi_store64ByteSendData(35, myBuf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_EMP_SETT);
-
-}
-
-void hwapi::emp_pollingOnOff(uint8_t on) const
-{
-    // on: 1=start polling the coin accepter  0=stop
-    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_POLL, on,0,0,0);
-
-}
-
-void hwapi::emp_startCoinAcceptance(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STARPPAY, 0,0,0,0);
-
-}
-
-void hwapi::emp_stopCoinAcceptance(void) const
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STOPPAY, 0,0,0,0);
-
-}
-
-
-
-void hwapi::emp_getAllParameters(struct T_emp *emp) const
-{
-    uint8_t leng, data[66], ii, pp;
-    epi_restoreEmpSettings(&leng, data);    // expected length = 64 byte
-
-    // get 64 bytes about EMP: see h-file
-
-    emp->gotSetup   = data[0];
-    emp->state      = data[1];
-    emp->shaft      = data[2];
-    emp->countryCode= uchar2uint(data[4], data[3]);
-    emp->scale      = data[5];
-    emp->decimals   = data[6];
-    for (ii=0; ii<16; ii++)
-        emp->coinValues[ii] = data[7+ii];
-    emp->coinAccept = uchar2uint(data[24], data[23]);
-    emp->tokenChannel = data[25];
-    emp->pollingRunning = data[26];
-    emp->paymentRunning = data[27];
-
-    pp=28;
-    for (ii=0; ii<16; ii++)
-    {
-        emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]);
-        pp+=2;
-    }
-    emp->routing= uchar2uint(data[61], data[60]);
-
-}
-
-/*
-static bool    emp_newCoin;
-static uint8_t emp_newCoinSignal;
-static uint16_t emp_newCoinValue;
-static uint8_t emp_newCoinError;
-
-uint8_t hwapi::emp_chkIfCoinInserted(void)
-{
-    // retval: 1=got coin 0xFF=emp reported an error  0=got nothing
-    //          comes only one time after each coin, vaslues are stored
-    uint8_t leng, data[8];
-
-    epi_restoreEmpCoinSignal(&leng, data);
-        // 5 byte per inserted coin:
-        //      data[0]:   1=got coin, data set valid
-        //      data[1]:   emp-signal of last inserted coin
-        //      data[2]:   emp-error or warning
-        //      data[3,4]: emp-value of last inserted coin 3=low byte
-
-    //epi_clearEmpCoinSignal();
-
-    if (data[0]>0)
-    {
-        emp_newCoin=data[0];  // anything came in, coin or error or both
-
-        if (data[0] & 0x80)
-        {
-            emp_newCoinError=data[4];
-        }
-        if (data[0] &0x0F)
-        {
-            emp_newCoinSignal=data[1];
-            emp_newCoinValue=uchar2uint(data[3], data[2]);
-        }
-        return emp_newCoin;
-    }
-    return 0;
-
-}
-
-uint8_t hwapi::emp_getInsertedCoinSignal(void)
-{
-    uint8_t uctmp=emp_newCoinSignal;
-    emp_newCoinSignal=0;    // return only once
-    return uctmp;
-
-}
-
-
-uint16_t hwapi::emp_getInsertedCoinValue(void)
-{
-    uint16_t uitmp=emp_newCoinValue;
-    emp_newCoinValue=0;    // return only once
-    return uitmp;
-}
-
-uint8_t hwapi::emp_getCoinError(void)
-{
-    uint8_t uctmp=emp_newCoinError;
-    emp_newCoinError=0;    // return only once
-    return uctmp;
-}
-*/
-
-uint8_t hwapi::emp_chkIfCoinInserted(void) const
-{
-    // retval: 0...16 coins left in FIFO
-    return epi_isNewCoinLeft();
-}
-
-
-void hwapi::emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const
-{
-
-    epi_restoreEmpCoinSignal(valid, signal, error, value);
-}
-
-uint8_t hwapi::emp_giveLastCoin(uint16_t *value, uint8_t *signal) const
-{
-    // retval: 0: NO coin stored  1: valid coin  2: got wrong coin or coin denied
-    // value: if retval1: value of the coin if reval=2: error number
-    // signal: channel nr reported from checker
-
-    uint8_t valid, chan, error;
-    uint16_t wert;
-
-    epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert);
-
-    if (valid && error==0xFF )
-    {
-        *value=wert;
-        *signal=chan;
-        return 1;
-    }
-
-    if (valid && error<0xFF )
-    {
-        *value=error;
-        *signal=chan;   // normally 0, but sometimes we get both
-        return 2;
-    }
-    return 0;
-}
-
-uint8_t hwapi::emp_returnLastCoin(uint16_t *value, uint8_t *signal) const
-{
-    // use this for coin changer
-
-    uint8_t valid, chan, error;
-    uint16_t wert;
-
-    epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert);
-
-    if (error)
-    {
-        *value=0;
-        *signal=error;
-        return 0;
-    }
-    *value=wert;
-    *signal=chan;
-    return valid;
-}
-
-// ----------------------------------------------------------------------------------------------------------
-// --------------------------------------------- Bill Validator -----------------------------------
-// ----------------------------------------------------------------------------------------------------------
-/*
-// Coin checker and changer mdb4.2 / section 5
-// Level 2 Commands  (predefined device msg acc. mdb manual and auto-poll)
-uint8_t hwapi::mdb_bill_startPolling(bool on)
-{
-    // send ether one command (from list below)
-    // or a poll command in the proper polling grid (e.g. every 100ms)
-    epi_storeConfig08(mdbPollBills,on);
-    //sendWRcmd_setSendCommand0(SENDDIRCMD_WR_CONF_08);
-    return 0;
-}
-
-// the following functions tell the DC to send a mdb command to any mdb slave
-// in opposite to mdb_sendData() the exact telegrams don't have to be formed here, DC does it.
-uint8_t hwapi::mdb_bill_reset()
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 1, 0, 0, 0);
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_setup()
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 2, 0, 0, 0);
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_security(uint16_t secLevel)
-{
-
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 3, uint8_t(secLevel), uint8_t(secLevel>>8), 0);
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_pollManually(void)
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 4, 0, 0, 0);
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable)
-{
-
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillType,
-                        uint8_t(billEnable), uint8_t(billEnable>>8),
-                        uint8_t(escrowEnable), uint8_t(escrowEnable>>8));
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_escrow(uint8_t action)
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 5, action, 0, 0);
-
-    return 0;
-}
-
-uint16_t hwapi::mdb_bill_stacker(void)
-{
-    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 6, 0, 0, 0);
-
-    return 0;
-}
-
-uint8_t hwapi::mdb_bill_expansion(uint8_t subCmd, uint8_t send[32])
-{
-    uint8_t sendbuf[34], nn;
-
-    // 1) insert subCmd into buffer
-    for (nn=0; nn<32; nn++)
-        sendbuf[nn+1]=send[nn];
-    sendbuf[0]=subCmd;
-    sendbuf[33]=0;
-    epi_storeMdbSendData(34, sendbuf);
-    sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_BillExp);
-    return 0;
-}
-
-
-uint8_t hwapi::mdb_bill_gotPollResponse(void)
-{
-    // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
-    return epi_getMdbResponse();       // request only once, then epi_getMdbRecLength()==0
-
-}
-
-
-uint8_t hwapi::mdb_bill_getDataLen(void)
-{
-    // return nr of byte received from any mdb device
-    return epi_getMdbRecLength();
-}
-
-uint8_t hwapi::mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize)
-{
-    uint8_t len, buf[64], LL;
-    len=epi_getMdbRecLength();
-    epi_restoreMdbRecData(buf);       // request only once, then epi_getMdbRecLength()==0
-    (maxBufferSize<len)?LL=maxBufferSize:LL=len;
-    for (uint8_t nn=0; nn<LL; nn++ )
-        mdb_data[nn]=buf[nn];
-    return 0;   // OK
-}
-
-*/
-
-
-// ----------------------------------------------------------------------------------------------------------
-// --------------------------------------------- MODEM ------------------------------------------------------
-// ----------------------------------------------------------------------------------------------------------
-/*
-uint8_t hwapi::mod_getHwState(struct Tmod_hw_state *mod_hw_state)
-{
-    mod_hw_state->powerRdBk=epi_restoreReadDIs(DIBYTE0, RB_VGSM);
-    if (epi_cntchk_swRs1toModem())
-        mod_hw_state->rsSwOk=1;
-    else
-        mod_hw_state->rsSwOk=0;
-
-    mod_hw_state->rsDrvOk=epi_cntchk_enabDrv01();   // can never be false
-    mod_hw_state->HwState=false;
-    mod_hw_state->CommState=false;
-    mod_hw_state->gotAnswer=false;
-
-    return 0;
-}
-
-
-uint8_t hwapi::mod_setCondition(uint16_t chgCmd)
-{
-    // e.g. change to state registered, sleep, open, off....
-    return uint8_t(chgCmd);
-}
-
-uint16_t hwapi::mod_getCondition(void)
-{
-    // e.g. now socket open
-
-    return 0;
-}
-
-bool    hwapi::mod_sendBufferFree(void)
-{
-    // sending allowed (before writing) and sending finished (after writing)
-
-    return 0;
-}
-
-void    hwapi::mod_wantReadData(uint16_t nrOfData)
-{
-    // start reading
-    nrOfData=0;
-
-}
-
-uint8_t hwapi::mod_sendDataBlk(uint16_t len, uint8_t *buf)
-{
-    len=buf[0];
-    return uint8_t(len);
-}
-
-uint16_t hwapi::mod_gotData(void)
-{
-    // return nr of received bytes
-
-    return 0;
-}
-
-uint8_t hwapi::mod_loadDataBlk(uint16_t len, uint8_t *buf)
-{
-    len=buf[0];
-    return uint8_t(len);
-
-
-}
-
-uint8_t hwapi::mod_setupSerial(struct TserialParams serialParameter)
-{
-    // Baudrate and so on...
-    return 0;
-}
-
-uint8_t hwapi::mod_getCurrentSerialSettings(struct TserialParams *serialParameter)
-{
-    // Baudrate and so on...
-
-    return 0;
-}
-*/
-
-
-
-
-
-
-
-
-
-
-// neu, 25.8.21
-
-
-
-
-QString hwapi::dc_getTxt4RsDiagWin(void) const
-{
-    return epi_getTxt4RsDiagWin();
-}
-
-void hwapi::dc_clrTxt4RsDiagWin(void) const
-{
-    epi_clrTxt4RsDiagWin();
-}
-
-QString hwapi::dc_get2ndTxt4RsDiagWin(void) const
-{
-    return epi_get2ndTxt4RsDiagWin();
-}
-
-void hwapi::dc_clr2ndTxt4RsDiagWin(void) const
-{
-    epi_clr2ndTxt4RsDiagWin();
-}
-
-QString hwapi::dc_getTxt4HsStateLine(void) const
-{
-    // Crash!
-    return epi_getTxt4HsStateLine();
-}
-
-void hwapi::dc_clrTxt4HsStateLine(void) const
-{
-    epi_clrTxt4HsStateLine();
-}
-
-
-QString hwapi::dc_getTxt4masterStateLine(void) const
-{
-    return epi_getTxt4masterStateLine();
-}
-
-void hwapi::dc_clrTxt4masterStateLine(void) const
-{
-    epi_clrTxt4masterStateLine();
-}
-
-QString hwapi::dc_getTxt4resultStateLine(void) const
-{
-    return epi_getTxt4resultStateLine();
-}
-
-void hwapi::dc_clrTxt4resultStateLine(void) const
-{
-    epi_clrTxt4resultStateLine();
-}
-
-QString hwapi::dc_getdataStateLine(void) const
-{
-    return epi_getTxt4dataStateLine();
-}
-
-void hwapi::dc_clrTxt4dataStateLine(void) const
-{
-    epi_clrTxt4dataStateLine();
-}
-
-
-QString hwapi::dc_getdatifLine(void) const
-{
-    return epi_getTxt4datifLine();
-}
-
-void hwapi::dc_clrTxt4datifLine(void) const
-{
-    epi_clrTxt4datifLine();
-}
-
-
-
-
-// using DC2 Bootloader
-
-void hwapi::bl_iniChain(void) const
-{
-    dcBL_iniChain();
-}
-
-
-bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const
-{
-    return dcBL_importBinFile(readBinFile, fileSize, withDispl);
-}
-
-uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const
-{
-    return dcBL_activatBootloader(sendData);
-}
-
-uint8_t hwapi::bl_startChain(void) const
-{
-    return dcBL_startChain();
-}
-
-uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const
-{
-    // minimum size of sendData-buffer: 5byte  retval: length
-
-    return dcBL_readBLversion(sendData);
-}
-
-uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const
-{
-    // minimum size of sendData-buffer: 5byte  retval: length
-    return dcBL_readFWversion(sendData);
-
-}
-
-uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const
-{
-// 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
-
-    return dcBL_prepareDC_BLcmd(Cmd, SendDataLength, sendData, outBuf);
-
-}
-
-uint8_t hwapi::bl_exitBL(uint8_t *sendData) const
-{
-    // minimum size of sendData-buffer: 5byte  retval: length
-    return dcBL_exitBL(sendData);
-}
-
-void hwapi::led_switchLedIllumination(uint8_t on) const
-{
-    if (on)
-    {
-
-    }
-
-}
-
-
-
-// neu, 25.3.23
-
-// ------------------------------------------------------------------------------------
-// 27.3.2023: Use Device-Controller's Bootloader to send hex-file
-// ------------------------------------------------------------------------------------
-
-void hwapi::bl_rebootDC(void) const
-{
-    uint8_t len, buf[20];
-
-    len=dcBL_restartDC(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-}
-
-void hwapi::bl_startBL(void) const {
-    uint8_t len, buf[20];
-    memset(buf, 0x00, sizeof(buf));
-
-    len=dcBL_activatBootloader(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-}
-
-bool hwapi::bl_checkBL(void) const
-{
-    uint8_t len, buf[20];
-
-    //len=dcBL_readBLversion(buf);
-    len=dcBL_readFWversion(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-
-    return (len > 0);
-}
-
-bool hwapi::bl_isUp(void) const
-{
-    uint8_t receivedData[160];
-    uint8_t LL;
-
-    memset(receivedData, 0x00, sizeof(receivedData));
-
-    LL=epi_getRawRecLength();
-    if (LL>0)
-    {
-        epi_getRawReceivedData(receivedData);
-        //epi_clrRawReceivedString();
-
-        //qDebug() << " *** got " << LL << " data bytes from BL: " <<
-         //   receivedData[0] << " " << receivedData[1] << " " << receivedData[2] << " " <<
-         //   receivedData[3] << " " << receivedData[4] << " " << receivedData[5] << " ";
-
-        // response to "readFWversion"
-        if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 &&
-            receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176)
-        {
-            dcBL_iniLoading();
-            return true;
-        }
-        // response to "start BL"
-        if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 &&
-            receivedData[3]==223 && receivedData[4] ==131 )
-        {
-            dcBL_iniLoading();
-            return true;
-        }
-
-    }
-    return false;
-}
-
-
-void hwapi::bl_sendAddress(u_int16_t blockNumber) const
-{
-    // send start address, nr of 64byte-block, start with 0
-    // will be sent only for folling block-numbers:
-    // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
-    uint32_t dcBL_BlkCtr=(uint32_t)blockNumber;
-    uint8_t  len, buf[20];
-
-    tslib_strclr(buf, 0, 20);
-    if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
-    {
-        dcBL_BlkCtr*=64;
-        len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf);   // make command string
-            // uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData)
-            // minimum size of sendData-buffer: 13byte    retval: length (9...13)
-        sendWRcmd_setSendBlock160(len, buf);        // send command to BL
-    }
-}
-
-uint8_t hwapi::bl_wasSendingAddOK(void) const
-{
-    // return val: 0: no response by now  1:error  10: OK
-
-    return dcBL_sendSuccess(0x21);
-    // return val: 0: no response by now  1:error  10: OK
-        // lastCommand=0x21 for sendAddr or 0x22 for send data
-
-}
-
-void hwapi::bl_openBinary(void) const
-{
-
-    dcBL_loadBinary(0);
-}
-
-void hwapi::bl_sendDataBlock(uint8_t length, u_int8_t *buffer) const
-{
-    // send 64 byte from bin file
-    uint8_t LL=length, sendBuf[80], sendLen;
-    if (LL>64) LL=64;
-
-    tslib_strclr(sendBuf,0,80);
-/*  hier ist alles richtig
-    qDebug() << "bl_sendDataBlock "<<LL<< " bytes: " << buffer[0] << " " << buffer[1] << " "
-     << buffer[2] << " " << buffer[3] << " " << buffer[4] << " " << buffer[5] << " "
-     << buffer[6] << " " << buffer[7] << " " << buffer[8] << " " << buffer[9] << " "
-    << buffer[61] << " " << buffer[62] << " " << buffer[63] << " " << buffer[64] << " "
-    << buffer[65] << " " << buffer[66] << " " << buffer[67] << " " << buffer[68] << " ";
-*/
-    sendLen=dcBL_prepareDC_BLcmd(0x22, LL, buffer, sendBuf);   // pack into protocol frame
-/*
-    qDebug() << "bl_sendDataBlock "<<sendLen<< " bytes: " << sendBuf[0] << " " << sendBuf[1] << " "
-     << sendBuf[2] << " " << sendBuf[3] << " " << sendBuf[4] << " " << sendBuf[5] << " "
-    << sendBuf[6] << " " << sendBuf[68] << " " << sendBuf[69] << " " << sendBuf[70] << " "
-    << sendBuf[71] << " " << sendBuf[72] << " " << sendBuf[73] << " " << sendBuf[74] << " ";
-*/
-    sendWRcmd_setSendBlock160(sendLen, sendBuf);                  // send 140 bytes
-    delay(100);
-}
-
-void hwapi::bl_sendLastBlock(void) const
-{
-    uint8_t len, buf[20];
-
-    len=dcBL_writeLastPage(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-}
-
-uint8_t hwapi::bl_wasSendingDataOK(void) const
-{
-    // return val: 0: no response by now  1:error  10: OK
-
-    return dcBL_sendSuccess(0x22);
-    // return val: 0: no response by now  1:error  10: OK
-        // lastCommand=0x21 for sendAddr or 0x22 for send data
-
-}
-
-void hwapi::bl_stopBL(void) const
-{
-    uint8_t len, buf[20];
-
-    len=dcBL_exitBL(buf);
-    sendWRcmd_setSendBlock160(len, buf);
-
-}
-/*
-bool hwapi::bl_isDiagAvailable(void) const
-{
-
-    return dcBL_checkForText();
-}
-
-
-QString hwapi::dc_getDiagText(void) const
-{
-    return dcBL_readText();    // read from 0...9 (oldest first)
-}
-*/
-
-/*
-// geht noch nicht //////
-void hwapi::bl_startSending(void) const
-{
-
-    dcBL_startLoading();
-}
-
-
-void hwapi::bl_sendFile(void) const
-{
-//qDebug()<<" HWAPI_BL_CYCL_ISrunning ";
-
-    dcBL_sendHexfile();
-
-}
-*/
-
-
-// ------------------------------------------------------------------------------------
-// 6.4.2023: new functions for coin collection and printing
-//            some new system functions
-// ------------------------------------------------------------------------------------
-
-// use:
-// 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 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 hwapi::rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const
-{
-    // return true if successful. could fail if more the 8 commands are waiting
-
-    uint8_t temp[66];
-    bool   b_ret;
-    /* in interfaces.h:
-    struct Trtc_DateTime
-    {
-       uint8_t rtc_hour;
-       uint8_t rtc_min;
-       uint8_t rtc_sec;
-       uint8_t rtc_dayOfMonth;
-       uint8_t rtc_month;
-       uint8_t rtc_year;
-       uint8_t rtc_dayOfWeek;
-    };
-    */
-    tslib_strclr(temp,0,66);
-    temp[0]= DateTime->rtc_hour;
-    temp[1]= DateTime->rtc_min;
-    temp[2]= DateTime->rtc_sec;
-    temp[3]= 20;
-    temp[4]= DateTime->rtc_year;
-    temp[5]= DateTime->rtc_month;
-    temp[6]= DateTime->rtc_dayOfMonth;
-    temp[7]= DateTime->rtc_dayOfWeek;
-    b_ret=longFDcmd_set(20,0,0,8,temp);
-    return b_ret;
-}
-
-bool hwapi::rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const
-{
-    epi_restoreExtendedTime(leng, data);
-    return true;
-
-/*
-     buf[0]=GlobTime.Hours;
-    buf[1]=GlobTime.Min;
-    buf[2]=GlobTime.Sec;
-    buf[3]=GlobTime.Year;
-    buf[4]=GlobTime.Month;
-    buf[5]=GlobTime.Day;
-    buf[6]=GlobTime.DOW;
-    buf[7]=' ';                   // immer auf 32bit auffüllen sonst Speicherproblem beim Master!
-    uitmp=GlobTime.MinOfDay;
-    buf[8]=swl_getOneByteFromUint(uitmp, 0);
-    buf[9]=swl_getOneByteFromUint(uitmp, 1);
-    buf[10]=' ';
-    buf[11]=' ';
-    ultmp=GlobTime.SecOfDay;
-    buf[12]=swl_getOneByteFromUlong(ultmp, 0);
-    buf[13]=swl_getOneByteFromUlong(ultmp, 1);
-    buf[14]=swl_getOneByteFromUlong(ultmp, 2);
-    buf[15]=swl_getOneByteFromUlong(ultmp, 3);
-
-    buf[16]=swl_isLeap(GlobTime.Year);
-    buf[17]=swl_getNextLeapYear(GlobTime.Year);
-    buf[18]=swl_getLastLeapYear(GlobTime.Year);
-    buf[19]=swl_hoursOfThisWeek(GlobTime.DOW, GlobTime.Hours);
-
-    uitmp=swl_minutesOfThisWeek(GlobTime.DOW, GlobTime.Hours, GlobTime.Min);
-    buf[20]=swl_getOneByteFromUint(uitmp, 0);    // 0=low byte   1=high byte
-    buf[21]=swl_getOneByteFromUint(uitmp, 1);
-
-    uitmp=swl_hoursOfThisMonth(GlobTime.Day, GlobTime.Hours);
-    buf[22]=swl_getOneByteFromUint(uitmp, 0);
-    buf[23]=swl_getOneByteFromUint(uitmp, 1);
-
-    uitmp=swl_minutesOfThisMonth(GlobTime.Day, GlobTime.Hours, GlobTime.Min);
-    buf[24]=swl_getOneByteFromUint(uitmp, 0);
-    buf[25]=swl_getOneByteFromUint(uitmp, 1);
-
-    uitmp=swl_GetDaysOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day);
-    buf[26]=swl_getOneByteFromUint(uitmp, 0);
-    buf[27]=swl_getOneByteFromUint(uitmp, 1);
-
-    uitmp=swl_GetHoursOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours);
-    buf[28]=swl_getOneByteFromUint(uitmp, 0);
-    buf[29]=swl_getOneByteFromUint(uitmp, 1);
-    buf[30]=0;
-    buf[31]=0;
-    ultmp= swl_GetMinutesOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day,
-                                GlobTime.Hours, GlobTime.Min);
-    buf[32]=swl_getOneByteFromUlong(ultmp, 0);
-    buf[33]=swl_getOneByteFromUlong(ultmp, 1);
-    buf[34]=swl_getOneByteFromUlong(ultmp, 2);
-    buf[35]=swl_getOneByteFromUlong(ultmp, 3);
-
-    buf[36]=rtc_getSqwaveSettings();
-    buf[37]=0;
-    buf[38]=0;
-    buf[39]=0;
-
-    ultmp= 0;       // Minutes of the Millenium
-    buf[40]=swl_getOneByteFromUlong(ultmp, 0);
-    buf[41]=swl_getOneByteFromUlong(ultmp, 1);
-    buf[42]=swl_getOneByteFromUlong(ultmp, 2);
-    buf[43]=swl_getOneByteFromUlong(ultmp, 3);
-
-    dc2prot_setReadData(44, buf);
-
- */
-
-}
-
-bool hwapi::sys_runCompleteTest(void) const
-{
-    // warning: lasts 20s in one pace
-    return sendFDcmd_set(149, 0,0, 0,0,0,0);
-}
-
-bool hwapi::sys_ready4sending(void) const
-{
-    // return true if a Json-file can be sent
-
-    // check free memory
-    uint8_t frei=FDLONG_STACKDEPTH - check4FDlongCmd();
-        // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte
-        // in check4FDlongCmd() steht wieviele Plaetze bereits belegt sind
-        // frei gibt also die Anzahl freier 64byte Bloecke zurueck
-        // das Json-File hat max 800 byte = 13 bloecke
-    if (frei<16)        // Puffer muss ganz leer sein! nicht dass was durcheinander kommt
-        return false;
-    return true;
-}
-
-bool hwapi::sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const
-{
-    // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
-    //      nrOfTemplate=1...32 if kindOfFile==6
-    //      content = content of the Json file, max 800byte ascii signs
-    // file is 0-terminated
-    // return false if sending is not possible, wait a second
-
-    uint8_t dateiArt, NummDesTempl;
-    uint8_t inhaltOfJson[802], temp[66];
-    uint16_t dateiLang, uitmp;
-    uint8_t nrOfBlocks;
-    uint8_t frei, bn=0;
-
-    dateiArt=kindOfFile;
-    NummDesTempl=nrOfTemplate;
-    tslib_strclr(inhaltOfJson,0,801);
-    dateiLang=tslib_strlen(content);
-    if (dateiLang>800) dateiLang=800;
-    tslib_strcpy(content, inhaltOfJson, dateiLang); // enthaelt genaue Laenge, Rest =0
-    nrOfBlocks=dateiLang/64;
-    if (dateiLang%64>0)
-        nrOfBlocks++;
-    dateiLang=nrOfBlocks;
-    dateiLang<<=6;  // auf volle 64byte aufgerundet
-
-    // check free memory
-    frei=FDLONG_STACKDEPTH - check4FDlongCmd();
-        // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte
-        // in check4FDlongCmd() steht wieviele Plaetze bereits belegt sind
-        // frei gibt also die Anzahl freier 64byte Bloecke zurueck
-        // das Json-File hat max 800 byte = 13 bloecke
-    if (frei<16)        // Puffer muss ganz leer sein! nicht dass was durcheinander kommt
-        return false;
-
-    // Start- und Stop auch als langes Kommando schicken
-    // PROBLEM: wuerden sie in einem anderen Batch gespeichert (short command stack),
-    //          dann kann die Reihenfolge nicht gewaehrleistet werden
-    //          Das Startkommando muss sicher zuerst kommen
-    //          Das Abschlusskommando muss sicher zuletzt kommen
-
-    tslib_strclr(temp,0,65);
-    temp[0]=dateiArt;
-    temp[1]=NummDesTempl;
-    longFDcmd_set(30, 0,0, 2,temp);      // sende "Starte-file-DL"
-    uitmp=0; bn=0;
-    do
-    {
-        biox_CopyBlock(inhaltOfJson, uitmp, temp, 0, 64);
-        longFDcmd_set(31,0, bn++, 64, temp);
-        uitmp += 64;
-        // uitmp<<=6;
-    } while(uitmp < dateiLang);
-
-    longFDcmd_set(32, 0,0, 0,temp);       // Abschluss
-
-    return true;
-}
-
-//char prn_dynPrnVal[8][8];
-bool hwapi::prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const
-// dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string
-//            like:     char prn_dynPrnVal[8][8];
-// return true if sending, false if cmd-stack is full
-{
-
-    uint8_t  temp[66];
-
-
-    tslib_strcpy(dynPrnVal, temp, 64); // Vorsicht, kann \0en enthalten
-    return longFDcmd_set(33,0,0, 64, temp);
-
-}
-
-bool hwapi::prn_printTemplate(uint8_t nrOftemplate) const
-    // print one of the templates loaded by Json prior
-    // nr = 1..32
-{
-    // return true if sending, false if cmd-stack is full
-    return sendFDcmd_set(152, 0,0, nrOftemplate,0,0,0);
-}
-
-void hwapi::log_getHoldAccountNumbers(uint32_t *accNr ) const
-    // returns all acc nrs of the backuped vault records
-    // use: uint32_t backupedAccNumbers[8]
-{
-    Q_UNUSED(accNr);
-}
-
-
-
-bool hwapi::log_selectVaultRecord(uint16_t accountNr ) const
-{
-    // return true if sending, false if cmd-stack is full
-    uint8_t dat1, dat2;
-
-    dat1=uint2uchar(accountNr, LOWBYTE);
-    dat2=uint2uchar(accountNr, HIGHBYTE);
-    return sendFDcmd_set(153, 0,0, dat1,dat2,0,0);
-
-}
-
-
-//request, isAvailable
-void hwapi::log_getVaultRecord(struct T_vaultRecord *retVR) const
-    // which was selected by: log_selectVaultRecord()
-    // to be forwarded to Ismas
-{
-    Q_UNUSED(retVR);
-}
-
-bool hwapi::prn_printAccountReceipt(void) const
-{
-    return sendFDcmd_set(154, 0,0, 0,0,0,0);
-}
-
-bool hwapi::prn_printTestTicket(void) const
-{
-    // return true if sending to DC OK, false if cmd-stack is full
-    return sendFDcmd_set(157, 0,0, 0,0,0,0);
-
-}
-
-bool hwapi::cash_startPayment(uint16_t amount) const
-{
-    uint8_t dat1, dat2;
-
-    epi_clearCurrentPayment();
-    dat1=uint2uchar(amount, LOWBYTE);
-    dat2=uint2uchar(amount, HIGHBYTE);
-    return sendFDcmd_set(155, 0,0, dat1,dat2,0,0);
-
-}
-
-uint32_t hwapi::getInsertedAmount(void) const
-{
-    return epi_CurrentPaymentGetAmount();
-}
-
-uint16_t hwapi::getLastInsertedCoin(void) const
-{
-    return epi_CurrentPaymentGetLastCoin();
-}
-
-bool hwapi::getAllInsertedCoins(uint16_t *types, uint16_t *values) const
-{
-    // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64
-    return epi_CurrentPaymentGetAllCoins(types, values);
-
-}
-
-
-bool hwapi::cash_cancelPayment(void) const
-    // and return coins
-{
-    // DB1: 1=encash    2=cancel & return coins
-    //      3=stop and keep coins in escrow
-    return sendFDcmd_set(156, 0,0, 2,0,0,0);
-}
-bool hwapi::cash_stopPayment(void) const
-    // and keep coins in escrow
-{
-    // DB1: 1=encash    2=cancel & return coins
-    //      3=stop and keep coins in escrow
-    return sendFDcmd_set(156, 0,0, 3,0,0,0);
-
-}
-// after ticket/goods issue:
-bool hwapi::vend_success(void) const
-    // conclude payment process, encash all inserted coins to vault. Printing was successful
-    // if possible return change
-{
-    // DB1: 1=encash    2=cancel & return coins
-    //      3=stop and keep coins in escrow
-    return sendFDcmd_set(156, 0,0, 1,0,0,0);
-
-}
-bool hwapi::vend_failed(void) const
-    // conclude payment process and return all inserted coins
-{
-    // DB1: 1=encash    2=cancel & return coins
-    //      3=stop and keep coins in escrow
-    return sendFDcmd_set(156, 0,0, 2,0,0,0);
-
-}
-
-
-
-
-
-
-uint8_t hwapi::mif_getCardType(QString cardholder) const
-    // return 1,2,3,4 = upper, lower access card, printer test, coin test
-    // cardholder: 7byte Name-String
-{
-    Q_UNUSED(cardholder);
-    return 0; // to satisfy compiler
-}
-
-uint64_t hwapi::sys_getWakeSource(void) const
-{
-    // retval: 6 bytes, bit coded, 1=event keeps DC awake
-     return epi_getWakeSources();
-}
-
-//void hwapi::sys_getDeviceConditions(struct T_moduleCondition *devCond) const
-void hwapi::sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const
-{
-    //uint8_t leng, data[66];
-    epi_restoreDeviceConditions(leng, data);
-}
-
-//void hwapi::sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const
-void hwapi::sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const
-{
-    epi_restoreDeviceConditions(leng, data);
-}
-
-
+/*
+ * API to the PSA2020 Hardware
+ * All data come in from device controller via serial interface and will be stored
+ * PI is updated every 100ms
+ * This api uses stored data and returns them in the following functions
+ * created: Q1/2020 TS until Q2/21
+ *
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <thread>
+#include <algorithm>
+
+#include <QFileInfo>
+
+#include "tslib.h"
+#include "hwapi.h"
+
+#include "sendWRcmd.h"
+#include "controlBus.h"
+#include "storeINdata.h"
+#include "dcBL.h"
+#include <QDebug>
+#include <../plugins/interfaces.h>
+
+
+static const QMap<QString, int> baudrateMap = {
+  {"1200"   ,   0}, {"9600"   ,   1}, {"19200"  ,   2}, {"38400"  ,   3},
+  {"57600"  ,   4}, {"115200" ,   5}
+};
+
+hwapi::hwapi(QWidget *parent) : QObject(parent)
+{
+    // constructor
+    //epi_resetAllDOs();
+    //PI_INI();
+    sendWRcmd_INI();
+
+    myDatif = new T_datif();
+}
+
+
+
+void hwapi::sub_storeSendingText(QByteArray *buf) const
+{
+
+    char local[70], copie[1350];    // 64byte more then max buffer size!
+    int LL, nn, len, maxruns=20;
+
+    epi_resetPrinterStack();
+    // make a copy of the incoming byteArray as the byteArray can not be moved (crash!)
+    tslib_strclr(copie, 0, 1350);
+    LL=buf->length();
+    for (nn=0; nn<LL; nn++)
+    {
+        copie[nn]=buf->at(nn);
+    }
+
+    tslib_strclr(local, 0, 66);
+    LL=buf->length();
+    if (LL>1280)
+    {
+        qDebug()<<"reducing text size from " << LL << " to 1280 bytes";
+        LL=1280;   // Limit size
+    } else
+        qDebug()<<"\n printing text with " << LL << " bytes: ";
+
+    do
+    {
+        len=tslib_getMinimum(LL, 64);
+        tslib_strclr(local, 0, 66);
+        for (nn=0; nn<len; nn++)
+        {
+            local[nn]=copie[nn];
+        }
+        local[64]=0;
+
+        // delete already printed part of big buffer
+        if (LL<=64)
+        {
+            // last block
+            local[LL]=10;
+            // new line = cmd to printer: "print, even if line is not filled"
+            LL=0;       // print complete
+        } else
+        {
+            LL-=64;
+            for (nn=0; nn<LL; nn++)
+            {
+                copie[nn]=copie[nn+64];
+            }
+            // pad remain with 0 (last but one block)
+            for (nn=LL; nn<64; nn++)
+            {
+                copie[nn]=0;
+            }
+        }
+
+
+        epi_storePrnText(local, uint8_t(len));    // no need to care for max PI size
+            // stores 64byte in PI with every call, maximal 20 calls (1280 byte)
+
+    } while(--maxruns>0 && LL>0);
+
+}
+
+
+// ------------------------------------------------------------------------------
+// Level 0 commands, interface
+// open, close, change serial interface
+// actually not neccessary as it is opened automatically on program start
+// start automatic READ requests
+// ------------------------------------------------------------------------------
+
+bool hwapi::dc_openSerial(int BaudNr, QString BaudStr,
+                          QString ComName, uint8_t connect) const {
+    // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
+    // BaudStr: for exapmle "19200"
+    // ComName: for example "COM48"
+    // connect: 0, 1
+    //qDebug() << "~~>LIB" << "dc_openSerial called... " ;
+
+    epi_setSerial(BaudNr, BaudStr, ComName, connect);
+
+    // Actions: open serial port with parameters
+    for (int i = 0; i < 10; ++i) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        if (dc_isPortOpen()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool hwapi::dc_closeSerial(void) const {
+    epi_closeSerial();
+    for (int i = 0; i < 10; ++i) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        if (!dc_isPortOpen()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool hwapi::dc_isPortOpen(void) const {
+    if (myDatif) {
+        T_prot* prot = myDatif->getProt();
+        if (prot) {
+            T_com *com = prot->getSerialPort();
+            if (com) {
+                return com->isPortOpen();
+            }
+        }
+    }
+    return false;
+    //return epi_isSerialPortOpen();
+}
+
+void hwapi::dc_autoRequest(bool on) const
+{
+    // automatically request ALL digital and analog sensors, get time/date, get status information
+    if (on)
+        epi_startEmmision(1);
+    else
+        epi_startEmmision(0);
+}
+
+/******************************************************************************/
+//
+//              LEVEL 2: Help-functions for hwapi::dc_updateDC.
+//
+/******************************************************************************/
+hwapi::DownloadResult hwapi::sendStatus(int ret) const {
+    switch (ret) {                      // return values of dc are:
+    case 0:                             // 0: no answer by now
+        return DownloadResult::NOP;     // 1: error
+    case 10:                            // 10: success
+        return DownloadResult::OK;
+    default:;
+    }
+    return DownloadResult::ERROR;
+}
+
+hwapi::DownloadResult hwapi::sendNextAddress(int bNum) const {
+    // sends address only if blockNumber is one of 0, 1024, 2048, 3072, 4096
+    int noAnswerCount = 0;
+    int errorCount = 0;
+    if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) {
+        qDebug() << "addr-block" << bNum << "...";
+        while (noAnswerCount <= 250) {
+            bl_sendAddress(bNum);
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            DownloadResult const res = sendStatus(bl_wasSendingAddOK());
+            if (res != DownloadResult::NOP) {
+                if (res == DownloadResult::ERROR) {
+                    if (++errorCount >= 10) {
+                        qCritical() << "addr-block" << bNum << "...FAILED";
+                        return res;
+                    }
+                } else { // res == DownloadResult::OK
+                    qInfo() << "addr-block" << bNum << "...OK";
+                    return res;
+                }
+            } else {
+                noAnswerCount += 1; // no answer by now
+            }
+        }
+        // wait max. about 3 seconds
+        return DownloadResult::TIMEOUT;
+    }
+    // blockNumber is not one of 0, 1024, 2048, 3072, 4096 -> do nothing
+    return DownloadResult::NOP;
+}
+
+hwinf::DownloadResult hwapi::sendNextDataBlock(QByteArray const &binary,
+                                               int bNum) const {
+    uint8_t local[66];
+    int const bAddr = bNum * 64;
+    int noAnswerCount = 0;
+    int errorCount = 0;
+
+    memcpy(local, binary.constData() + bAddr, 64);
+    local[64] = local[65] = 0x00;
+
+    qDebug() << "data for addr" << bAddr << "...";
+
+    while (noAnswerCount <= 250) {
+        bl_sendDataBlock(64, local);
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        DownloadResult const res = sendStatus(bl_wasSendingDataOK());
+        if (res != DownloadResult::NOP) {
+            if (res == DownloadResult::ERROR) {
+                if (++errorCount >= 10) {
+                    qCritical() << "data for addr" << bAddr << "...FAILED";
+                    return res;
+                }
+            } else {
+                qInfo() << "data for addr" << bAddr << "...OK";
+                return res;
+            }
+        } else {
+            noAnswerCount += 1; // no answer by now
+        }
+    }
+    // wait max. about 3 seconds
+    return DownloadResult::TIMEOUT;
+}
+
+hwinf::DownloadResult hwapi::dc_downloadBinary(QByteArray const &b) const {
+    int const nBlocks = (((b.size())%64)==0) ? (b.size()/64) : (b.size()/64)+1;
+
+    qInfo() << "total number of bytes to send to dc" << b.size();
+    qInfo() << "total number of blocks to send to dc" << nBlocks;
+
+    int bNum = 0;
+    DownloadResult res = DownloadResult::OK;
+    while (res != DownloadResult::ERROR &&  bNum < nBlocks) {
+        if ((res = sendNextAddress(bNum)) != DownloadResult::ERROR) {
+            if ((res = sendNextDataBlock(b, bNum)) != DownloadResult::ERROR) {
+                bNum += 1;
+            }
+        }
+    }
+    if (res != DownloadResult::ERROR) {
+        bl_sendLastBlock();
+    }
+    return res;
+}
+
+bool hwapi::startBootloader() const {
+    qDebug() << "starting bootloader...";
+    int nTry = 5;
+    while (--nTry >= 0) {
+        bl_startBL();
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        if (bl_isUp()) {
+            qInfo() << "starting bootloader...OK";
+            std::this_thread::sleep_for(std::chrono::milliseconds(500));
+            return true;
+        }
+    }
+    qCritical() << "starting bootloader...FAILED";
+    return false;
+}
+
+bool hwapi::stopBootloader() const {
+    qDebug() << "stopping bootloader...";
+    int nTry = 5;
+    while (--nTry >= 0) {
+        bl_stopBL();
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        if (!bl_isUp()) {
+            qInfo() << "stopping bootloader...OK";
+            return true;
+        }
+    }
+    qCritical() << "stopping bootloader...FAILED";
+    return false;
+}
+
+// br is a index into a table, used for historical reasons.
+bool hwapi::openSerial(int br, QString baudrate, QString comPort) const {
+    qDebug() << "opening serial" << br << baudrate << comPort << "...";
+    if (dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect
+        qInfo() << "opening serial" << br << baudrate << comPort << "...OK";
+        return true;
+    }
+    qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED";
+    return false;
+}
+
+bool hwapi::closeSerial(QString comPort) const {
+    qDebug() << "closing serial" << comPort << "...";
+    if (dc_closeSerial()) {
+        qInfo() << "closing serial" << comPort << "...OK";
+        return true;
+    } else {
+        qCritical() << "closing serial" << comPort << "...FAILED";
+    }
+    return false;
+}
+
+bool hwapi::resetDeviceController() const {
+    qDebug() << "resetting device controller...";
+    if (stopBootloader()) { // first stop a (maybe) running bootloader
+        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+        dc_OrderToReset();
+        // wait maximally 3 seconds, before starting bootloader
+        std::this_thread::sleep_for(std::chrono::milliseconds(1500));
+        qInfo() << "resetting device controller...OK";
+        return true;
+    }
+    return false;
+}
+
+QByteArray hwapi::loadBinaryDCFile(QString filename) const {
+    qDebug() << "loading dc binary" << filename << "...";
+
+    QFile file(filename); // closed in destructor call
+    if (!file.exists()) {
+        qCritical() << file.fileName() << "does not exist";
+        return QByteArray();
+    }
+    if (!file.open(QIODevice::ReadOnly)) {
+        qCritical() << "cannot open file" << file.fileName();
+        return QByteArray();
+    }
+    qInfo() << "loading dc binary" << filename << "...OK";
+    return file.readAll();
+}
+
+bool hwapi::downloadBinaryToDC(QString const &bFile) const {
+    qDebug() << "sending" << bFile << "to dc...";
+    QByteArray const dcBinary = loadBinaryDCFile(bFile);
+    if (dcBinary.size() > 0) {
+        if (dc_downloadBinary(dcBinary) != DownloadResult::OK) {
+            qCritical() << "sending" << bFile << "to dc...FAILED";
+            return false;
+        } else {
+            qInfo() << "sending" << bFile << "to dc...OK";
+        }
+    } else {
+        qCritical() << "sending" << bFile << "to dc...FAILED";
+        qCritical() << "loading binary" << bFile << "FAILED";
+        return false;
+    }
+    return true;
+}
+
+/******************************************************************************/
+//
+//                        LEVEL 3: hwapi::dc_updateDC.
+//
+/******************************************************************************/
+bool hwapi::dc_updateDC(QString bFile, QString br, QString serial) const {
+    if (!baudrateMap.contains(br)) { // sanity check
+        qCritical() << "passed wrong baudrate" << br;
+        return false;
+    }
+
+    qDebug() << "updating dc: " << bFile << br << serial << "...";
+
+    if (!openSerial(baudrateMap.value(br), br, serial)) {
+        return false;
+    }
+    if (!resetDeviceController()) {
+        closeSerial(serial);
+        return false;
+    }
+    if (!startBootloader()) {
+        closeSerial(serial);
+        return false;
+    }
+    if (!downloadBinaryToDC(bFile)) {
+        stopBootloader();
+        closeSerial(serial);
+        qCritical() << "updating dc: " << bFile << br << serial << "...FAILED";
+        return false;
+    }
+
+    qInfo() << "updating dc: " << bFile << br << serial << "...OK";
+
+    stopBootloader();
+    closeSerial(serial);
+    return true;
+}
+
+/******************************************************************************/
+//
+//                   LEVEL 3: hwapi::dc_updatePrinterTemplate
+//
+/******************************************************************************/
+bool hwapi::dc_updatePrinterTemplate(enum FileTypeJson type,
+                                     QVector<int> templatesIdx,
+                                     QVector<QString> fnames,
+                                     QString br,
+                                     QString serial) const {
+    // sanity checks
+    if (!baudrateMap.contains(br)) {
+        qCritical() << "passed wrong baudrate" << br;
+        return false;
+    }
+    if (templatesIdx.size() != fnames.size()) {
+        qCritical() << "list sizes must be equal" << br;
+        return false;
+    }
+    if (!std::all_of(templatesIdx.cbegin(), templatesIdx.cend(),
+                    [](int i) { return i >= 1 && i <= 32; })) {
+        qCritical() << "wrong template indices";
+        return false;
+    }
+    if (type != FileTypeJson::PRINTER) {
+        qCritical() << "wrong file type" << (uint8_t)type;
+        return false;
+    }
+
+    qDebug() << "updating: " << fnames << br << serial << "...";
+
+    if (!serial.isNull()) {
+        if (!openSerial(baudrateMap.value(br), br, serial)) {
+            return false;
+        }
+    }
+
+    int nTry = 50;
+    while (!sys_ready4sending()) { // wait max. 5 seconds
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        if (--nTry <= 0) {
+            qCritical() << "sys not ready for sending";
+            if (!serial.isNull()) {
+                closeSerial(serial);
+            }
+            return false;
+        }
+    }
+
+    bool ret = true;
+    for (int i = 0; i < fnames.size(); ++i) {
+        QFile file(fnames[i]);
+        if (file.exists() && file.open(QIODevice::ReadOnly)) {
+            QByteArray ba = file.readAll();
+            if (ba.size() <= 800) { // max. size is 800 bytes
+                if (sys_sendJsonFileToDc((uint8_t)(type),
+                                          templatesIdx[i],
+                                          (uint8_t *)ba.data())) {
+                    std::this_thread::sleep_for(std::chrono::seconds(1));
+                    qInfo() << "sent file" << fnames[i] << "to dc";
+                }
+            }
+        } else {
+            qCritical() << fnames[i] << "!!! does not exist!!!";
+            ret = false;
+            continue;
+        }
+    }
+    if (!serial.isNull()) {
+        closeSerial(serial);
+    }
+    return ret;
+}
+
+bool hwapi::dc_printTemplate(enum FileTypeJson type,
+                             QVector<int> templateIdx,
+                             QString br,
+                             QString serial) const {
+    // sanity checks
+    if (!baudrateMap.contains(br)) {
+        qCritical() << "passed wrong baudrate" << br;
+        return false;
+    }
+    if (!std::all_of(templateIdx.cbegin(), templateIdx.cend(),
+                    [](int i) { return i >= 1 && i <= 32; })) {
+        qCritical() << "wrong template indices";
+        return false;
+    }
+    if (type != FileTypeJson::PRINTER) {
+        qCritical() << "wrong file type" << (uint8_t)type;
+        return false;
+    }
+
+    qDebug() << "printing: " << templateIdx << br << serial << "...";
+
+    if (!serial.isNull()) {
+        if (!openSerial(baudrateMap.value(br), br, serial)) {
+            return false;
+        }
+    }
+
+    int nTry = 50;
+    while (!sys_ready4sending()) { // wait max. 5 seconds
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        if (--nTry <= 0) {
+            qCritical() << "sys not ready for sending";
+            if (!serial.isNull()) {
+                closeSerial(serial);
+            }
+            return false;
+        }
+    }
+
+    bool ret = true;
+    for (int i = 0; i < templateIdx.size(); ++i) {
+        if (prn_printTemplate(templateIdx[i])) {
+            qDebug() << "printing template" << templateIdx[i];
+            std::this_thread::sleep_for(std::chrono::seconds(3));
+        } else {
+            ret = false;
+            continue;
+        }
+    }
+    if (!serial.isNull()) {
+        closeSerial(serial);
+    }
+    return ret;
+
+}
+
+// ------------------------------------------------------------------------------
+// Level 1, control device-controller (functions of µC)
+// check serial connection to deviceController
+// read response from DC2 (input data)
+// some test function for serial communication
+// also Bootloader is here
+// ------------------------------------------------------------------------------
+
+void hwapi::dc_requTestResponse() const
+{
+    sendWRcmd_setSendCommand0(SENDDIRCMD_TestSerial);
+}
+
+bool hwapi::dc_readAnswTestResponse() const
+{
+    return epi_getResult_serialTestOK();
+}
+
+uint8_t hwapi::dc_isRequestDone(void) const
+{
+    // retval:  0: request is still in progress
+    //          1: answer from DC2 was OK
+    //          2: wrong answer from DC2
+    return epi_getResultOfLastRequest();
+}
+
+uint16_t hwapi::dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const
+{
+    // get data back in *pl, max 64 byte, can be used for diagnosis
+    // 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
+
+    return epi_getLastPayLoad( plBufSiz,  payLoad);
+
+}
+
+void hwapi::dc_setWakeFrequency(uint8_t period) const
+{
+    // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
+    // change wake signal period to 1...64s
+    sendWRcmd_setSendCommand4(SENDDIRCMD_setWakeFrequ, period,0,0,0);
+}
+
+void hwapi::dc_OrderToReset(void) const
+{
+    uint8_t len, buf[160];
+
+    len=dcBL_restartDC(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+    //sendWRcmd_setSendCommand0(SENDDIRCMD_MakeReset);
+    // not needed, sendWRcmd_setSendBlock160() starts sending as well...
+}
+
+QString hwapi::dc_getSerialState(void) const
+{
+// geht
+    return epi_getTxt4comStateLine();
+}
+
+void hwapi::dc_clrSerialStateText(void) const
+{
+    epi_clrTxt4comStateLine();
+}
+
+
+
+void hwapi::bl_sendDataDirectly(uint8_t length, uint8_t *buf) const
+{
+    // send without protocol frame, needed for the DC bootloader
+    sendWRcmd_setSendBlock160(length, buf);
+
+}
+
+uint8_t hwapi::getRawRecLength(void) const
+{
+    return epi_getRawRecLength();
+}
+
+uint8_t hwapi::getRawReceivedData(uint8_t *receivedData) const
+{
+    return epi_getRawReceivedData(receivedData);
+}
+
+
+
+
+QString hwapi::dc_getSerialParams(void) const
+{
+    return epi_getSlaveParamSTR();
+}
+
+QString hwapi::dc_getHWversion(void) const
+{
+    return epi_loadGenerals(0);
+}
+
+QString hwapi::dc_getSWversion(void) const
+{
+    return epi_loadGenerals(1);
+}
+
+QString hwapi::dc_getState(void) const
+{
+    return epi_loadGenerals(2);
+}
+
+
+// ------------------------------------------------------------------------------
+// Level 2  DC2-onboard devices
+//          WR: set time
+//          RD. get time, get measure, get test results
+// ------------------------------------------------------------------------------
+
+// get UID, get time/date   test results   memory,  RTC  analog values
+
+// ----------------------------------------------------------------------------------------------------------
+// Date and Time
+// ----------------------------------------------------------------------------------------------------------
+
+uint8_t hwapi::rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const
+{
+//    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);
+    uint8_t H, M, S;
+    uint16_t unused16;
+    uint32_t unused32;
+
+    epi_getTime(&H, &M, &S);
+    rtc_DateTime->rtc_hour=H;
+    rtc_DateTime->rtc_min=M;
+    rtc_DateTime->rtc_sec=S;
+
+    epi_getDate(&H, &M, &S);
+    rtc_DateTime->rtc_year=H;
+    rtc_DateTime->rtc_month=M;
+    rtc_DateTime->rtc_dayOfMonth=S;
+
+    epi_getToday(&H, &unused16, &unused32);
+    rtc_DateTime->rtc_dayOfWeek=H;
+    return 0;
+}
+
+uint8_t hwapi::rtc_setDateTime(void) const
+{
+    sendWRcmd_setSendCommand0(SENDDIRCMD_setTime);
+    return 0;
+}
+
+
+void hwapi::rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const
+{
+    epi_getTime(hh, mm, ss);
+}
+
+void hwapi::rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const
+{
+    epi_getDate(yy, mm, dd);
+}
+
+uint8_t hwapi::rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const
+{
+    // dow=day of week, 1=monday...7
+    // minOfToday: 0=midnight...1439= 23:59
+    // secOfToday: 0=midnight...86399= 23:59:59
+
+    epi_getToday(dow, minOfToday, secOfToday);
+    return 0;
+}
+
+bool hwapi::rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const
+{
+    return epi_isLeapYear(lastLeapYear, NextLeapYear);
+}
+
+
+bool hwapi::rtc_isLeapYear(void) const
+{
+    return epi_isLeapYear();
+}
+
+void hwapi::rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const
+{
+    epi_getSpecialWeekTimeDate(DayOfWeek, HoursOfWeek, MinutesOfWeek);
+}
+
+void hwapi::rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const
+{
+    epi_getSpecialMonthTimeDate(DayOfMonth, HoursOfMonth, MinutesOfMonth);
+}
+
+void hwapi::rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const
+{
+    epi_getSpecialYearTimeDate(DayOfYear, HoursOfYear, MinutesOfYear);
+}
+
+
+QString hwapi::rtc_getTimStr() const
+{
+    uint8_t hh,  mm,  ss, buf[20], nn;
+    QString qbuf;
+
+    qbuf.clear();
+    for (nn=0; nn<20; nn++) buf[nn]=0;
+    epi_getTime(&hh, &mm, &ss);
+    GetTimeString(hh, mm, ss, HourSys24h, MITSEK, buf); // about 12byte long
+    for (nn=0; nn<20; nn++) qbuf[nn]=buf[nn];
+
+    return qbuf;
+}
+
+QString hwapi::rtc_getDatStr() const
+{
+    uint8_t day,  month,  year, buf[20], nn;
+    QString qbuf;
+
+    qbuf.clear();
+    for (nn=0; nn<20; nn++) buf[nn]=0;
+    epi_getDate(&year, &month, &day);
+    GetDateString(day, month, 0x20, year, DateFormatDeutsch, 0, buf);
+    for (nn=0; nn<20; nn++)
+        qbuf[nn]=buf[nn];
+
+    return qbuf;
+}
+
+QString hwapi::rtc_getTimDatStr() const
+{
+    // style: 0: hh:mm    1: hh:mm:ss
+    QString qbuf;
+
+    qbuf.clear();
+    qbuf.append(rtc_getTimStr());
+    qbuf.append("   ");
+    qbuf.append(rtc_getDatStr());
+    return qbuf;
+}
+
+
+
+
+
+// UID
+void hwapi::dc_getUID8byte(uint8_t *buf8byteUid) const
+{
+    epi_getUIDdec(buf8byteUid);
+}
+
+QString hwapi::dc_getUIDstr() const
+{
+    return epi_getUIDstr();
+}
+
+uint64_t hwapi::dc_getUIDnumber(void) const
+{
+    uint64_t retval=0;
+    uint8_t buf8byteUid[12], nn;
+
+    epi_getUIDdec(buf8byteUid);
+    for (nn=8; nn>0; nn--)
+    {
+        retval+=buf8byteUid[nn-1];
+        retval<<=8;     // *256
+    }
+    return retval;
+}
+
+
+
+uint32_t hwapi::dc_getTemperature(void) const
+{
+    //
+    return epi_loadMeasureValue(MEASCHAN_TEMPERATURE);
+}
+
+QString hwapi::dc_getTemperaturStr(void) const
+{
+    return epi_getSlaveTemperatureStr();
+}
+
+
+uint32_t hwapi::dc_getVoltage(void) const
+{
+    // in mV, e.g. 12300 = 12,3V
+    return epi_loadMeasureValue(MEASCHAN_VOLTAGE);
+}
+
+QString hwapi::dc_getVoltagStr(void) const
+{
+    return epi_getSlaveVoltageStr();
+}
+
+bool hwapi::dc_mainFuseIsOk(void) const
+{
+    uint32_t ulong=epi_loadMeasureValue(MEASCHAN_VOLTAGE); // in mV, e.g. 12300 = 12,3V
+    if (ulong>3000)
+        return true;
+    return false;
+}
+
+// ------------------------------------------------------------------------------
+// Level 3: digital outputs and simple switching of connected devices
+//          simple processes like flashing a led or open flap for 1s
+// ------------------------------------------------------------------------------
+
+// Locks:
+uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const
+{
+    // dir 0=off 1=up 2=down
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEUP_LOCK ,dir,0,0,0);
+    return 0;
+}
+
+uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const
+{
+    // dir 0=off 1=up 2=down
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEDN_LOCK ,dir,0,0,0);
+    return 0;
+}
+
+void hwapi::lock_switchVaultDoor(void) const
+{
+
+    sendWRcmd_setSendCommand0(SENDDIR_OPENVAULT);
+}
+
+void hwapi::coin_switchRejectMotor(uint8_t dir) const
+{
+
+    sendWRcmd_setSendCommand4(SENDDIR_REJMOT_ON, dir, 0,0,0);
+}
+
+void hwapi::coin_rejectCoins(void) const
+{
+
+    sendWRcmd_setSendCommand0(SENDDIR_REJMOT_RUN);
+}
+
+
+void hwapi::led_switchLedService(uint8_t on) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDINSIDE, on, 0, 0, 0);
+}
+
+void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDTICKET, on, ton, tof, 0);
+}
+
+void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDPAD, on, ton, tof, 0);
+}
+
+void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDSTART, on, ton, tof, 0);
+}
+
+void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LEDCOIN, on, ton, tof, 0);
+}
+
+void hwapi::fan_switchFan(bool on) const
+{
+    //return epi_storeDOsToSend(DOBYTE3, FAN_ON, on);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_FAN, on, 0, 0, 0);
+}
+
+void hwapi::alarm_switchSiren(bool on) const
+{
+    //return epi_storeDOsToSend(DOBYTE4, LAERM, on);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_LAERM, on, 0, 0, 0);
+}
+
+void hwapi::bar_OpenBarrier(bool open) const
+{
+    //return epi_storeDOsToSend(DOBYTE4, REL1, open);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_REL1, open, 0, 0, 0);
+}
+
+void hwapi::ptu_switchWake(bool WAKEACTIVE) const
+{
+    //return epi_storeDOsToSend(DOBYTE1, CTS_PTU, WAKEACTIVE);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_WAKEPTU, WAKEACTIVE,0,0,0);
+}
+
+// AUX-IO's or barcode reader
+void hwapi::aux_power(bool on) const
+{
+//    return epi_storeDOsToSend(DOBYTE2, BARC_POW_ON, on);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXPWR, on,0,0,0);
+}
+
+void hwapi::aux_setUsage(uint8_t PinDirection) const
+{
+    // bit 0= Aux1    bit5=Aux6  1=output  0=input with pullup
+
+    //    return epi_storeDOsToSend(DOBYTE6, nr, PinDirection);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXDDR, PinDirection,0,0,0);
+}
+
+void hwapi::aux_setOutputs(uint8_t PinIsHigh) const
+{
+    // PinIsHigh bit 0..5 =Aux1...6  1=output high  0=set output low
+
+    //return epi_storeDOsToSend(DOBYTE5, nr, PinIsHigh);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_AUXOUT, PinIsHigh,0,0,0);
+}
+
+void hwapi::lock_switchContactPower(bool on) const
+{
+    //epi_storeDOsToSend(DOBYTE2, U_SW_ON, on);
+    sendWRcmd_setSendCommand4(SENDDIRCMD_UCONTACT_ON, on, 0,0,0);
+}
+
+void hwapi::prn_switchPower(bool on) const
+{
+    // also switches and enables serial driver
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN2_SWONOFF, on,0,0,0);
+    indat_storePrinterPower(on);
+    // PRINTER-ON/OFF zusätzlich statisch abspeichern
+    //       Status-request soll nur gesendet werden wenn der Drucker ein ist
+    //       Status-Abfrage (hier in HWapi) gibt 0 zurück wenn power-off
+    // dito mit allen anderen Geräten!
+
+    // pi ---> storeINdata.cpp  speichert diese statische Info (printer on/off) UND
+    // auch alles rückgelesene
+
+}
+
+
+void hwapi::mif_readerOn(bool on) const
+{
+    // DC2 also switches and enables serial driver
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0);
+}
+
+void hwapi::mif_creatAtbCard(uint8_t cardType) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, cardType, 0,0,0);
+}
+
+
+void hwapi::mod_switchPower(bool on) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_SWONOFF, on,0,0,0);
+}
+
+void hwapi::mod_switchWake(bool WAKEACTIVE) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_WAKE, WAKEACTIVE,0,0,0);
+}
+
+void hwapi::mdb_switchPower(bool on) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_POWER, on,0,0,0);   
+}
+
+void hwapi::mdb_switchWake(bool WAKEACTIVE) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_WAKE, WAKEACTIVE,0,0,0);
+}
+
+void hwapi::credit_switchPower(bool on) const
+{    
+    sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_ON, on,0,0,0);
+}
+
+void hwapi::credit_switchWake(bool WAKEACTIVE) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_WAKE, WAKEACTIVE,0,0,0);
+}
+
+void hwapi::shut_move(bool open) const
+{
+    // true:open  false:close
+    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_MOV, open, 0,0,0);
+}
+
+void hwapi::esc_moveFlaps(uint8_t flap ) const
+{
+    // 0: close both  1: open take-flap   2: open return
+    sendWRcmd_setSendCommand4(SENDDIRCMD_ESCRO_MOV, flap, 0,0,0);
+}
+
+
+// ------------------------------------------------------------------------------
+// Level 3: digital inputs of connected devices
+// ------------------------------------------------------------------------------
+
+
+
+uint8_t hwapi::door_getSwitches(void) const
+{
+    // retval         // bit0: upper door  1: low door  2:vault door
+    uint8_t ret;
+
+    ret= epi_getDI_doorSwitches();
+        // bit0: upper door  1: low door  2:vault door
+    ret &= 0x08;
+    return ret;
+}
+
+bool    hwapi::door_isUpperDoorOpen(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_doorSwitches();
+        // bit0: upper door  1: low door  2:vault door
+    if (ret &  1)
+        return true;
+    return false;
+}
+
+bool    hwapi::door_isLowerDoorOpen(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_doorSwitches();
+        // bit0: upper door  1: low door  2:vault door
+    if (ret &  2)
+        return true;
+    return false;
+}
+
+bool    hwapi::vault_isVaultDoorOpen(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_doorSwitches();
+        // bit0: upper door  1: low door  2:vault door
+    if (ret &  4)
+        return true;
+    return false;
+}
+
+
+uint8_t hwapi::vault_getSwitches(void) const
+{
+    // retval bit0: cash box,  bit 1: bill box
+    uint8_t ret;
+
+    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
+    ret&=0x03;
+    return ret;
+}
+
+bool hwapi::vault_isCoinVaultIn(void) const
+{
+    uint8_t ret;
+
+    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
+    if (ret & 1)
+        return true;
+    return false;
+}
+
+bool hwapi::vault_isBillVaultIn(void) const
+{
+    uint8_t ret;
+
+    ret=epi_getDI_vaultSwitches();      // bit0: cash box    1: bill box in
+    if (ret & 2)
+        return true;
+    return false;
+}
+
+
+
+uint8_t hwapi::door_getLocks(void) const
+{
+    // retval bit0: upper lever is up
+    //        bit1: upper lever is down
+    //        bit2: lower lever is up
+    //        bit3: lower lever is down
+
+    uint8_t ret;
+
+    ret= epi_getDI_lockSwitches();
+        // retval: bit 0: upper lockbar up   bit1: upper lockbar is down
+        //         bit 2: lower lockbar up   bit1: lower lockbar is down
+    ret&=0x0F;
+    return ret;
+}
+
+bool hwapi::door_upperDoorIsLocked(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_lockSwitches();
+    if (ret & 2)
+        return true;
+    return false;
+}
+
+bool hwapi::door_upperDoorIsUnlocked(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_lockSwitches();
+    if (ret & 1)
+        return true;
+    return false;
+}
+
+bool hwapi::door_lowerDoorIsLocked(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_lockSwitches();
+    if (ret & 8)
+        return true;
+    return false;
+}
+
+bool hwapi::door_lowerDoorIsUnlocked(void) const
+{
+    uint8_t ret;
+
+    ret= epi_getDI_lockSwitches();
+    if (ret & 4)
+        return true;
+    return false;
+}
+
+
+
+bool    hwapi::bar_optoIn1isOn(void) const
+{
+    uint8_t ret=epi_getDI_optos();
+        // bit0: opto in 1    1: opto in 2
+    if (ret & 1)
+        return true;
+    return false;
+}
+
+bool    hwapi::bar_optoIn2isOn(void) const
+{
+    uint8_t ret=epi_getDI_optos();
+        // bit0: opto in 1    1: opto in 2
+    if (ret & 2)
+        return true;
+    return false;
+}
+
+
+uint8_t hwapi::aux_getAuxInputs(void) const
+{
+    // retval: bit0=Aux1....Bit5=Aux6
+    //          0: input low  1:input high
+
+    uint8_t ret=epi_getDI_auxIn();
+    // bit0: auxin 1  ...  5: auxin 6
+    ret &=0x3F;
+    return ret;
+}
+
+bool hwapi::ptu_WakeINisActive(void) const
+{
+    return epi_getDI_ptuWake();
+}
+
+bool hwapi::mdb_WakeINisActive(void) const
+{
+    return epi_getDI_mdbWake();
+}
+
+bool hwapi::prn_readyINisActive(void) const
+{
+    return epi_getDI_prnReady();
+}
+
+bool hwapi::coid_isAttached(void) const
+{
+    return epi_getDI_CoinAttach();
+}
+
+bool hwapi::coin_escrowIsOpen(void) const
+{
+    return epi_getDI_CoinEscrow();
+}
+
+bool hwapi::mif_cardIsAttached(void) const
+{
+    return epi_getDI_mifareCardTapped();
+}
+
+//bool hwapi::mod_WakeINisActive(void)
+//{
+//    return epi_getDI_modemWake();
+//}
+
+
+
+bool hwapi::door_isContactPowerOn(void) const
+{
+    return  epi_getDI_contactPwr();
+}
+
+bool hwapi::mif_isMifarePowerOn(void) const
+{
+    bool mo=indat_isMifareOn();
+    bool mi=epi_getDI_mifarePwr();
+    if (mo && mi)
+        return true;
+    return false;
+}
+
+bool hwapi::mdb_testIsmdbTxDon(void) const
+{
+    return  epi_getDI_mdbTxd();
+}
+
+bool hwapi::aux_isAuxPowerOn(void) const
+{
+    return  epi_getDI_auxPwr();
+}
+
+bool hwapi::mod_isGsmPowerOn(void) const
+{
+    return  epi_getDI_gsmPwr();
+}
+
+bool hwapi::cred_isCreditPowerOn(void) const
+{
+    return  epi_getDI_creditPwr();
+}
+
+bool hwapi::prn_isPrinterPowerOn(void) const
+{
+    return  epi_getDI_printerPwr();
+}
+
+uint8_t hwapi::prn_PrnFuseIsOk(void) const
+{
+    //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off
+    if (!epi_getDO_printerPwr())
+        return 2;       // unknown as printer power is off
+    if (epi_getDI_printerPwr())
+        return 1;       // printer voltage is OK
+    return 0;       // fuse blown
+}
+
+bool hwapi::mdb_isMdbPowerOn(void) const
+{
+    return  epi_getDI_mdbPwr();
+}
+
+
+bool hwapi::cash_getRejectMotorHomePos(void) const
+{
+    return epi_getDI_rejectMotor_homepos();
+}
+
+uint8_t hwapi::cash_getLowPaperSensor(void) const
+{
+    // 0: Sensor sees paper 1: no paper 99: off
+    return  epi_getDI_npe_sensor();
+
+}
+
+// ------------------------------------------------------------------------------
+// Level1,2,3     RD request commands
+// ------------------------------------------------------------------------------
+
+// the following requests can be sent manually
+//   or automatically in background by:   void hwapi::dc_autoRequest(bool on)
+//   in other words:
+//   if automatic-reading is on then there's no need to send any of these commands!
+
+
+void hwapi::request_DC2serialConfig() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_SERCONF);
+}
+
+void hwapi::request_DC2_HWversion() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_HWversion);
+}
+
+void hwapi::request_DC2_SWversion() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_SWversion);
+}
+
+void hwapi::request_DC2_condition() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_CONDITION);
+}
+
+void hwapi::request_DC2_UID() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_UID);
+}
+
+void hwapi::request_DC2_TimeAndDate() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_TIME);
+}
+
+void hwapi::request_DC2_analogues() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_ANALOGS);
+}
+
+void hwapi::request_DC2_digitalInputs() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_DIG_INPUTS);
+}
+
+void hwapi::request_DC2_digitalOutputs() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_DIG_OUTPUTS);
+}
+
+// ------------------------------------------------------------------------------
+// the folowing device state requests are deployed only if device is powered up:
+
+void hwapi::request_PrinterHwState() const
+{
+
+    sendWRcmd_setSendCommand0(SEND_REQU_PRN_STATE);
+}
+
+void hwapi::request_PrinterCurrentFonts() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_PRN_FONTS);
+}
+
+void hwapi::request_PrinterStateComplete() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_PRN_ALL);
+}
+
+
+
+
+
+void hwapi::request_MifareReaderState() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
+}
+
+void hwapi::request_MifareCardType() const
+{
+    //uint8_t blkAdr=0;
+    //sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, blkAdr,0,0,0);
+    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
+}
+
+void hwapi::request_MifareAtbType() const
+{
+    //sendWRcmd_setSendCommand0(SEND_REQU_MIF_ATB_TYPE);
+    sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE);
+
+}
+
+void hwapi::request_MifareID() const
+{
+    uint8_t sequenceNumber=0;
+    sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, sequenceNumber,0,0,0); // 1st data = card sequence =blk nr (0...15)
+}
+
+void hwapi::request_MifareData(uint8_t dataBlockNumber) const
+{   
+    if (dataBlockNumber<12)     // 1k cards return 12 data blocks, 4k cards would return 54 data blocks (not implemented)
+        sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15)
+}
+
+
+
+void hwapi::request_MDB_Status() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETSTAT);
+}
+
+//void hwapi::request_MDB_wakeInLine() const
+//{
+//    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK);
+//}
+
+void hwapi::request_MDB_lastResponse() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETRESP);
+}
+
+void hwapi::request_EMP_allParameters() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETALL);
+}
+
+void hwapi::request_EMP_lastCoin() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETCOIN);
+
+}
+
+
+
+// ------------------------------------------------------------------------------
+// Level 3: readback digital outputs of connected devices
+//          these functions are not needed for normal operation
+//          but can be used to test and verify conditions
+
+//          There are two options:
+//              1) the important things like power-outputs and wake lines are
+//              measured at DC2-terminals (after transistors) and come as input to DC-board
+//              2) others like Leds are read from µC-pins by DC-board
+// ------------------------------------------------------------------------------
+
+bool hwapi::test_getDO_mdbRXtst(void) const
+{
+    return  epi_getDO_mdbRxTestOut();
+}
+
+uint8_t hwapi::lock_getDO_motors(void) const
+{
+    // bit0: upper lock forward    bit 1 backward
+    // bit2: lower lock forward    bit 3 backward
+
+    return epi_getDO_motorOuts();
+}
+
+uint8_t hwapi::test_serialState(void) const
+{
+    // test on-board signals for the serials
+    // serial drv on/off, Serial mux1, Serial mux2
+
+    uint8_t ret=epi_getDO_serialSwitch();
+        // serial drv on/off, Serial mux1, Serial mux2
+    ret &=0x07;
+    return ret;
+}
+
+bool hwapi::test_serialIsOn(void) const
+{
+    return epi_getDO_serialDriverIsOn();
+}
+
+bool hwapi::test_serialMux1isSetToPrinter(void) const
+{
+    return epi_getDO_serialMux1isSetToPrinter();
+    // mux1 off: serial is switched to printer
+}
+
+bool hwapi::test_serialMux1isSetToModem(void) const
+{
+    return  epi_getDO_serialMux1isSetToModem();
+    // mux1 on: serial is switched to modem
+}
+
+bool hwapi::test_serialMux2isSetToCredit(void) const
+{
+    return epi_getDO_serialMux2isSetToCredit();
+    // mux2 off: serial is switched to credit card terminal
+}
+
+bool hwapi::test_serialMux2isSetToMifare(void) const
+{
+    return epi_getDO_serialMux2isSetToMifare();
+    // mux2 on: serial is switched to mifare reader
+}
+
+bool hwapi::led_coinIsOn(void) const
+{
+    return epi_getDO_led_coin();
+}
+
+bool hwapi::led_frontIsOn(void) const
+{
+    return epi_getDO_led_front();
+}
+
+bool hwapi::led_ticketIsOn(void) const
+{
+    return epi_getDO_led_ticket();
+}
+
+bool hwapi::led_pinIsOn(void) const
+{
+    return epi_getDO_led_pin();
+}
+
+bool hwapi::led_StartIsOn(void) const
+{
+    return epi_getDO_led_start();
+}
+
+bool hwapi::led_insideIsOn(void) const
+{
+    return epi_getDO_led_inside();
+}
+
+bool hwapi::fan_isOn(void) const
+{
+    return epi_getDO_fan();
+}
+
+bool hwapi::siren_isOn(void) const
+{
+    return epi_getDO_sirene();
+}
+
+bool hwapi::bar_relayIsOn(void) const
+{
+    return epi_getDO_relay();
+}
+
+bool hwapi::ptu_WakeOutIsOn(void) const
+{
+    return epi_getDO_ptuWake();
+}
+
+bool hwapi::aux_powerIsOn(void) const
+{
+    return epi_getDO_auxPower();
+}
+
+
+bool hwapi::coin_shutterIsOpen(void) const
+{
+    return epi_getDO_coinShutterOpen();
+}
+
+bool hwapi::coin_shutterTestOutput(void) const
+{
+    return epi_getDO_coinShutterTest();
+}
+
+uint8_t hwapi::coin_escrowFlapOpened(void) const
+{
+    // retval: 1:return flap is open   2:take flap is open    0:closed
+
+    return epi_getDO_coinEscrow();
+}
+
+
+
+
+
+
+
+
+// ------------------------------------------------------------------------------
+// Level4   devices are operated by DC
+//          processes with more then one devices
+//          timer controlled or long term processes
+// ------------------------------------------------------------------------------
+
+
+
+
+void hwapi::sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker,
+                               uint8_t kindOfMifareReader, uint8_t suppressSleep,
+                               uint8_t kindOfModem, uint8_t kindOfCredit) const
+{
+    uint8_t buf[64];
+
+    tslib_strclr(buf,0,64);
+    buf[0]=kindOfPrinter;
+    buf[1]=kindOfCoinChecker;
+    buf[2]=kindOfMifareReader;
+    buf[3]=suppressSleep;
+    buf[4]=kindOfModem;
+    buf[5]=kindOfCredit;
+
+    epi_store64ByteSendData(6, buf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_DEVICE_PARA);
+
+
+}
+
+void hwapi::request_ReadbackDeviceSettings() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_DEVICE_PARA);
+}
+
+
+void hwapi::readback_DeviceSettings(uint8_t *length, uint8_t *data) const
+{
+
+    epi_restoreRbDeviceSettings(length, data);
+/*
+            buf66[0]=devPara.kindOfPrinter;
+            buf66[1]=devPara.kindOfCoinChecker;
+            buf66[2]=devPara.kindOfMifareReader;
+            buf66[3]=devPara.suppressSleepMode;
+            buf66[4]=devPara.kindOfModem;
+            buf66[5]=devPara.kindOfCreditcard;
+            buf66[6]=devPara.CoinEscrow;
+            buf66[7]=devPara.CoinRejectUnit;
+            buf66[8]=devPara.CoinShutter;
+            buf66[9]=devPara.BillAcceptor;
+            buf66[10]=devPara.usevaultLock;
+            buf66[11]=devPara.autoAlarm;
+            buf66[12]=devPara.autoOpen;
+            buf66[13]=devPara.printAccReceipt;
+            buf66[14]=devPara.printDoorReceipt;
+            buf66[15]=devPara.printTokenTicket;
+            uitmp=devPara.VaultFullWarnLevel;
+            buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
+            buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
+            uitmp=devPara.VaultFullErrorLevel;
+            buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
+            buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
+
+*/
+}
+
+// ....................................................................................
+
+void hwapi::sendMachineID(uint16_t customerNr, uint16_t machineNr,
+                          uint16_t borough, uint16_t zone,
+                          uint16_t alias,   char *location) const
+{
+    uint8_t buf[64];
+
+    tslib_strclr(buf,0,64);
+    buf[0]=uint2uchar(customerNr, LOWBYTE);
+    buf[1]=uint2uchar(customerNr, HIGHBYTE);
+    buf[2]=uint2uchar(machineNr, LOWBYTE);
+    buf[3]=uint2uchar(machineNr, HIGHBYTE);
+    buf[4]=uint2uchar(borough, LOWBYTE);
+    buf[5]=uint2uchar(borough, HIGHBYTE);
+    buf[6]=uint2uchar(zone, LOWBYTE);
+    buf[7]=uint2uchar(zone, HIGHBYTE);
+    buf[8]=uint2uchar(alias, LOWBYTE);
+    buf[9]=uint2uchar(alias, HIGHBYTE);
+    tslib_strcpy(location, &buf[10], 32);
+
+    epi_store64ByteSendData(42, buf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_MACHINE_ID);
+
+
+}
+
+void hwapi::request_ReadbackMachineID() const
+{
+    sendWRcmd_setSendCommand0(SEND_REQU_MACINE_ID);
+}
+
+
+void hwapi::readback_machineIDdata(uint8_t *length, uint8_t *data) const
+{
+    epi_restoreMachineIDsettings(length, data);
+/*
+            buf66[0]=swl_getOneByteFromUint(machPara.customerNumber, GETLOWBYT);
+            buf66[1]=swl_getOneByteFromUint(machPara.customerNumber, GETHIGHBYT);
+            buf66[2]=swl_getOneByteFromUint(machPara.machineNumber, GETLOWBYT);
+            buf66[3]=swl_getOneByteFromUint(machPara.machineNumber, GETHIGHBYT);
+            buf66[4]=swl_getOneByteFromUint(machPara.borough, GETLOWBYT);
+            buf66[5]=swl_getOneByteFromUint(machPara.borough, GETHIGHBYT);
+            buf66[6]=swl_getOneByteFromUint(machPara.zone, GETLOWBYT);
+            buf66[7]=swl_getOneByteFromUint(machPara.zone, GETHIGHBYT);
+            buf66[8]=swl_getOneByteFromUint(machPara.alias, GETLOWBYT);
+            buf66[9]=swl_getOneByteFromUint(machPara.alias, GETHIGHBYT);
+            for (pp=0; pp<32; pp++)
+                buf66[10+pp]=machPara.location[pp];
+            dc2prot_setReadData(42, buf66);
+
+*/
+}
+
+
+// ....................................................................................
+
+
+
+
+
+static uint16_t hwapi_shutterTime;
+
+// locks, 2.Level: (Motor stops automatical on end switch or by 5s timeout)
+uint8_t hwapi::lock_openUpperDoor(void) const
+{
+    //bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
+        // commands are defined in PIdefines.h
+    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 1, 0, 0, 0);
+        // paras:   dat2: 1=upper door lock   2=lower
+        //          dat1: 1=open              2=close
+    return 0;
+}
+
+
+uint8_t hwapi::lock_closeUpperDoor(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 2, 0, 0, 0);
+    return 0;
+}
+
+uint8_t hwapi::lock_openLowerDoor(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 1, 0, 0, 0);
+    return 0;
+}
+
+uint8_t hwapi::lock_closeLowerDoor(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 2, 0, 0, 0);
+    return 0;
+}
+
+void hwapi::shut_openOnce(void) const
+{
+    // and close automatic after shutter time
+    uint16_t zeit=hwapi_shutterTime;
+    zeit/=100;
+    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYTIME, uint8_t(zeit) ,0,0,0);
+
+}
+
+void hwapi::shut_openForCoin(bool start) const
+{
+    // start=true: start opening flap if coin is attached
+    // start=false: stop process
+
+    uint16_t zeit=hwapi_shutterTime;
+    zeit/=100;
+    sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYCOIN, uint8_t(start), uint8_t(zeit),0,0);
+
+}
+
+void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const
+{
+    // after this time without retrigger the flap is closed
+    //sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_SENDTIME, timeIn100ms,0,0,0);
+    hwapi_shutterTime=timeIn_ms;
+
+}
+
+
+void hwapi::esc_takeMoney(void) const
+{
+    // and close automatically after escrow time (1s)
+    sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_TAKE);
+}
+
+void hwapi::esc_returnMoney(void) const
+{
+    // and close automatically after time
+    sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_GIVE);
+
+}
+
+
+
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// --------------------------------------------- MIFARE -----------------------------------------------------
+// ----------------------------------------------------------------------------------------------------------
+
+
+uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const
+{
+    // retval 0=OK 1=error host buffer too small
+
+    /* data description:
+
+    new fast version:
+    byte 0= still the same: 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: reader state 1=ok 0=nok
+    byte 2: card present (0,1)
+    byte 3: card selected (0)
+    byte 4: card type: 0...5
+    byte 5: card allowed (0=no  1=MifareClassic 1k or 4k)
+    byte 6: CardSize: 1 or 4 (kB)
+    byte 7: length of UID 4 or 7 (byte)
+    */
+
+    return epi_restoreMifState(buf, maxBufferSize);
+}
+
+/* OLD 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 "ATB25-1.8"
+16: 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
+*/
+
+bool hwapi::mif_readerIsOK(void) const
+{
+
+    uint8_t buf[40];    // old version had 40 bytes, new version only 8
+    uint8_t ret= epi_restoreMifState(buf, 40);
+    if (ret==0 && buf[0]>1 && buf[1]>0)
+            return 1;
+    return 0;   // error
+}
+
+bool hwapi::mif_cardAttached(void) const
+{
+
+    uint8_t buf[40];
+    uint8_t ret= epi_restoreMifState(buf, 40);
+    if (ret==0 && buf[0]>1 && buf[2]>0) // reader OK
+        if (buf[16]>0)
+            return 1;
+    return 0;   // error
+}
+
+uint8_t hwapi::mif_readResult(void) const
+{
+    // result: 0: unknown or still in progress
+    //         1: card read successful
+    //         2: reading error
+
+    uint8_t buf[40];
+    uint8_t ret= epi_restoreMifState(buf, 40);
+    // data read successful && Reader OK && card attached && ...
+    if (ret==0  && buf[1]>0 && buf[2]>0)
+    {
+//        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
+
+        if (buf[0]==1 || buf[0]==5 || buf[0]==6)
+            return 2;
+        if (buf[0]==4)
+            return 1;
+
+    }
+    return 0;   // error
+
+}
+
+
+QString hwapi::mif_cardUID(void) const
+{
+    QString myStr;
+
+    uint8_t buf[65], ret;
+
+    //uint8_t ret= epi_restoreMifState(buf, 40);
+    myStr.clear();
+/*
+    if (ret==0 && buf[0]==4 && buf[3]>0 && buf[16]>0 && buf[19]>0)
+    {
+        // UID in buf[22...29]
+        for (int ii=0;ii<8; ii++)
+        {
+
+            myStr+=QString::number(buf[ii+22],16);
+            myStr+=" ";     // make a gap between numbers
+        }
+    }
+*/
+
+    ret=epi_restoreMifData(0, buf, 64);
+    if (ret)
+        return myStr;   // return empty string on error
+    else
+    {
+        buf[8]=0;
+        //myStr.append(buf);
+        for (int ii=0;ii<8; ii++)
+        {
+
+            myStr+=QString::number(buf[ii],16); // 16: return in hex format
+            myStr+=" ";     // make a gap between numbers
+        }
+
+        return myStr;
+    }
+
+
+}
+
+
+uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const
+{
+    // blkNr=0...11    return buf[64]   maxBufferSize must be >=64
+
+    return epi_restoreMifData(blkNr, buf, maxBufferSize);
+    // blkNr=0...11    return buf[64]
+
+}
+
+QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const
+{
+    // with blockNumber=0...11
+    QString myStr;
+    uint8_t buf[66];
+
+    myStr.clear();
+    if (blockNumber>11)
+        return myStr;
+
+    epi_restoreMifData(blockNumber, buf, 66);
+
+    for (int ii=0; ii<64; ii++)
+    {
+        //myStr+=QString::number(buf[ii],10);     // decimals as ascii
+        myStr+=QString::number(buf[ii],16);     // hex numbers as ascii
+        myStr+=" ";     // make a gap between numbers
+    }
+    return myStr;
+}
+
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// --------------------------------------------- PRINTER ----------------------------------------------------
+// ----------------------------------------------------------------------------------------------------------
+
+// already above:
+// void hwapi::prn_switchPower(bool on)             0x2A01
+// bool hwapi::prn_readyINisActive(void)
+// bool hwapi::prn_isPrinterPowerOn(void)
+// void hwapi::request_PrinterHwState()             0x2A02
+// void hwapi::request_PrinterCurrentFonts()        0x2A12
+// void hwapi::request_PrinterStateComplete()   // =request_PrinterHwState + request_PrinterCurrentFonts
+
+uint8_t hwapi::prn_getHwState(struct Tprn_hw_state *prn_hw_state) const
+{
+    // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok?
+    //        printer on error or ok?
+    uint8_t prnHWstate[20];
+
+    epi_restorePrinterState(prnHWstate);
+        // byte 1...6 come right from printer, see printer manual
+        // byte 0 = all important infos:
+        // byte 0 = 0: prnter OK,  >0: error
+        // bit0: paper low  1: no paper    2: temperature error
+        // 3: head open     4: paper jam in cutter
+        // 6: no response   7: bad response from printer
+
+    prn_hw_state->powerRdBk = epi_getDI_printerPwr();
+    prn_hw_state->rsSwOk    = epi_getDO_serialMux1isSetToPrinter();   // mux1 off: serial is switched to printer
+    prn_hw_state->rsDrvOk   = epi_getDO_serialDriverIsOn();
+    prn_hw_state->ReadyLine = epi_getDI_prnReady();
+
+    if (prnHWstate[0]==0)
+        prn_hw_state->inIdle = true;    // no errors
+    else
+        prn_hw_state->inIdle = false;    // off or errors
+
+    if (prnHWstate[0] & 1)
+        prn_hw_state->paperNearEnd=true;
+    else
+        prn_hw_state->paperNearEnd = false;
+
+    if (prnHWstate[0] & 2)
+        prn_hw_state->noPaper=true;
+    else
+        prn_hw_state->noPaper = false;
+
+    if (prnHWstate[0] & 4)
+        prn_hw_state->ErrorTemp=true;
+    else
+        prn_hw_state->ErrorTemp = false;
+
+    if (prnHWstate[0] & 8)
+        prn_hw_state->HeadOpen=true;
+    else
+        prn_hw_state->HeadOpen = false;
+
+    if (prnHWstate[0] & 16)
+        prn_hw_state->cutterJam=true;
+    else
+        prn_hw_state->cutterJam = false;
+
+
+    if (prnHWstate[0] & 64)
+        prn_hw_state->noResponse=true;
+    else
+        prn_hw_state->noResponse = false;
+
+    if (prnHWstate[0] & 128)
+        prn_hw_state->badResponse=true;
+    else
+        prn_hw_state->badResponse = false;
+    return prnHWstate[0];
+
+}
+
+bool hwapi::prn_isUpAndReady(void) const
+{
+    struct Tprn_hw_state prnHwNow;
+
+    prn_getHwState(&prnHwNow);
+    if (prnHwNow.inIdle && prnHwNow.rsSwOk && prnHwNow.rsDrvOk && prnHwNow.powerRdBk )
+        return true;
+    return false;
+}
+
+void hwapi::prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const
+{
+    uint8_t prnFonts[22];
+
+    epi_restorePrinterFonts(&prnFonts[0]);
+    prn_fonts->currFont  = prnFonts[0];
+    prn_fonts->currSize  = prnFonts[1];
+    prn_fonts->currHeigth= prnFonts[2];
+    prn_fonts->currWidth = prnFonts[3];
+    prn_fonts->nowBold   = prnFonts[4];
+    prn_fonts->nowInvers = prnFonts[5];
+    prn_fonts->nowUnderlined= prnFonts[6];
+    prn_fonts->currDensity  = prnFonts[7];
+    prn_fonts->currSpeed    = prnFonts[8];
+    prn_fonts->nowAligned   = prnFonts[9];
+
+}
+
+
+void hwapi::prn_sendText(QByteArray *buf) const
+{
+    sub_storeSendingText(buf);
+    epi_storeUserOfSendingTextBuffer(1,0,0,0,0);  // 1=print text
+
+
+}
+
+
+void hwapi::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const
+{
+    // send three byte through to printer, see printers manual
+    sendWRcmd_setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3);
+}
+
+void hwapi::prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const
+{
+    // send four byte through to printer, see printers manual
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_ESC_CMD, para1, para2, para3, para4);
+}
+
+void hwapi::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const
+{
+    // send 5 byte: byte 0,1: speed  5...250 mm/s
+    //              byte2: density   0....(25)....50
+    //              byte3: alignment    'l', 'c', 'r' = left, center, right
+    //              byte4: orientation  0, 90, 180    = 0°, 90°, 180° rotation (by now not supported!)
+    // not batched! don't use twice within 100ms
+
+    uint8_t buf[10];
+    uint16_t uitmp;
+
+    uitmp=paperSpeed;
+    buf[0]=uint8_t(uitmp);
+    uitmp>>=8;
+    buf[1]=uint8_t(uitmp);
+    buf[2]=density;
+    buf[3]=alignment;
+    buf[4]=orientation;
+    buf[5]=0;
+    epi_store64ByteSendData(5, buf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_SETUP);
+}
+
+void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const
+{
+    //direction: 1=forward 2=backward
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_MOVE, wayInMm, direction, 0,0);
+}
+
+
+void hwapi::prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const
+{
+    // font = kind of font 0...8
+    // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge
+    // width:  0...4   0=1x  1=2x   2=4x (huge!)  3=8x 4=16x (3,4 make no sense)
+    // heigth: 0...7 = 1x...8x  only 0,1,2,(3) make sense
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETFONT, font, size, width, height);
+}
+
+
+void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETLETT, bold, invers, underlined, 0);
+}
+
+void hwapi::prn_cut(uint8_t kindof) const
+{
+    // kindof = 1: full cut  2: partial cut   3=eject (5xLF + full cut)
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CUT, kindof,0,0,0);
+}
+
+void hwapi::prn_newLine(uint8_t nrOfLines) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LF, nrOfLines, 0, 0, 0);
+}
+
+void hwapi::prn_printCompleteFontTable(void) const
+{
+    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_FONTTAB);
+}
+
+
+void hwapi::prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const
+{
+    uint8_t buf[66], nn;
+    //uint16_t uitmp;
+
+    if (dataLeng>58)
+        dataLeng=58;
+
+    buf[0]=kindOf;
+    buf[1]=withText;
+    buf[2]=offset;
+    buf[3]=rotation;
+    buf[4]=dataLeng;
+    // rest: Barcode-data:
+    for (nn=0; nn<dataLeng; nn++)
+        buf[5+nn]=data[nn];
+
+    epi_store64ByteSendData( (5+dataLeng), buf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_BC);
+}
+
+void hwapi::prn_sendQRdata(QByteArray *buf) const
+{
+    // maximal 150 alphanummeric bytes
+    sub_storeSendingText(buf);
+    epi_storeUserOfSendingTextBuffer(2,0,0,0,0);  // 2= print QRcode
+}
+
+void hwapi::prn_printQRcode(void) const
+{
+    // which was sent before
+    sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_QR);
+}
+
+void hwapi::prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const
+{    
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LOGO_FL, nrOfLogo, offset, 0, 0);
+    pri_TD_addText("Hallo");
+}
+
+
+// .........................................................
+// Parking Ticket (print out) designer
+// .........................................................
+
+static QByteArray ticketTemplate;
+
+void hwapi::pri_startTicketDesign(void) const
+{
+    ticketTemplate.clear();
+
+}
+
+int hwapi::pri_TD_getCurrentSize(void) const
+{
+    return ticketTemplate.size();
+}
+
+bool hwapi::pri_TD_addText(QByteArray text) const
+{
+    if ((ticketTemplate.length() + text.length())>1278)
+        return false;
+    ticketTemplate.append(text);
+    qDebug()<<"\nText added "<<ticketTemplate;
+    return true;
+}
+
+bool hwapi::pri_TD_addValue(int val) const
+{
+    QString  tmpStr;
+    tmpStr.setNum(val,10);      // up to 12 chars
+    if (ticketTemplate.length()>1266)
+        return false;
+    ticketTemplate.append(tmpStr);
+    return true;
+}
+
+bool hwapi::pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const
+{
+    // always add 8 byte to the ticket layout:  ESC & group & attribute & parameter1...5
+    /* complete list of possible commands:
+        group 50 : paper
+            attribute 10 :  move forward
+                  p1: wayInMm p2: direction
+            attribute 11 : cut
+                  p1: kind of, 1=full 2=partial, 3=eject
+            attribute 12 : new line(s)
+                  p1: nr of lines 1...100
+
+        group 51 : fonts
+            attribute 10 : kind of font     see description above
+                  p1: possible: 0...22, expedient: 5...11
+            attribute 11 : font size
+                  p1: 6...20  12=normal   6=tiny
+            attribute 12 : font width
+                  p1: 0...4
+            attribute 13 : font heigth
+                  p1: 0...7
+            attribute 14 : switch bold print on/off
+                  p1: 0=off  1=on
+            attribute 15 : switch invers print on/off
+                  p1: 0=off  1=on
+            attribute 16 : switch underlined print on/off
+                  p1: 0=off  1=on
+
+        group 52 : print graphics
+            attribute 10 : print barcode with dynamic data 6 and 7
+                  p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above
+            attribute 11 : print QRcode with preset data
+
+            attribute 12 : print Logo
+                 p1=nrOfLogo, p2=offset
+
+        group 53 : print dynamics
+            attribute 10 : 1...8 = print dynData 0..7 at this place
+
+*/
+
+
+    char  tmpStr[10];
+
+    // command has always fixed length of 8 byte
+    if (ticketTemplate.length()>1270)
+        return false;
+    if (group<50 || group>59)
+        return false;
+    if (attribute<10 || attribute>30)
+        return false;
+
+    tmpStr[0]=0x1B;     // ESC
+    tmpStr[1]=group;
+    tmpStr[2]=attribute;
+    tmpStr[3]=p1;
+    tmpStr[4]=p2;
+    tmpStr[5]=p3;
+    tmpStr[6]=p4;
+    tmpStr[7]=p5;
+
+    ticketTemplate.append(tmpStr, 8);
+
+
+    qDebug()<<"\ncmd added "<<ticketTemplate;
+    return true;
+}
+
+bool hwapi::pri_TD_addNewLine(void) const
+{
+
+    if (ticketTemplate.length()>1277)
+        return false;
+    ticketTemplate.append("\n");
+    return true;
+}
+
+bool hwapi::pri_TD_addSign(char sign) const
+{
+    if (ticketTemplate.length()>1277)
+        return false;
+    ticketTemplate.append(sign);
+    return true;
+}
+
+
+char hwapi::prn_clearDocument(uint8_t documentNumber) const
+{
+    if (documentNumber>15)
+        return false;
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CLEARDOC, documentNumber, 0, 0, 0);
+    return true;
+}
+
+
+bool hwapi::prn_store_Document(uint8_t documentNumber ) const
+{
+    // send to DC
+    // documentNumber=0...15, stored in Eeprom
+    // maximal 1280 bytes each
+    // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc)
+    // 0x1B=start of embedded command (next 7bytes = command)
+
+    if (documentNumber>15)
+        return false;
+    sub_storeSendingText(&ticketTemplate);
+    epi_storeUserOfSendingTextBuffer(3,documentNumber,0,0,0);  // 3=store document
+    return true;
+}
+
+
+bool hwapi::prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const
+{
+    if (documentNumber>15)
+        return false;
+    epi_store64ByteSendData(64, &(dynTicketData->licensePlate[0]));
+    sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_DOC, documentNumber, 0, 0, 0);
+    return true;
+}
+
+
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// ------------------------------------------- MDB Bus ------------------------------------------------------
+// ----------------------------------------------------------------------------------------------------------
+
+
+
+void hwapi::mdb_sendBusReset(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_RES, 0,0,0,0);
+
+}
+
+#define mdb_device_coinChk  0
+#define mdb_device_changer  1
+#define mdb_device_bill     2
+//#define mdb_device_credit   3   // obsolete
+
+
+void hwapi::mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_SENDCMD, toMdbDevice, mdbCommand, 0,0);
+
+}
+
+void hwapi::mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const
+{
+    // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
+    uint8_t myBuf[64], ii;
+
+    tslib_strclr(myBuf, 0, 64);
+    myBuf[0]=toMdbDevice;
+    myBuf[1]=mdbCommand;
+    if (nrOfData>34) nrOfData=34;
+    myBuf[2]=nrOfData;
+    for (ii=0; ii<nrOfData; ii++)
+        myBuf[ii+3]=dataBuffer[ii];
+    epi_store64ByteSendData(37, myBuf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_SNDMSG);
+}
+
+
+
+bool hwapi::mdb_busIsReadyToWork() const
+{
+    return epi_restoreMdbBusReady();
+}
+
+bool hwapi::mdb_deviceVoltageOK() const
+{
+    return epi_restoreMdbV12Ready();
+}
+
+bool hwapi::mdb_busVoltageOk() const
+{
+    return epi_restoreMdbV5Ready();
+}
+
+uint8_t hwapi::mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
+                                         uint8_t *responseLength, uint8_t *responseBuffer) const
+{
+    // fromDevice: device nr from which data was requested 0,1,2,3
+    // lastRequest: sent mdb command
+    // responseLength: nr of payload data (after mdb-ack) 0...34
+    // responseBuffer holds payload data (answer from mdb device)
+    // return val: mdb result of this request: 1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
+
+
+    uint8_t leng, ResData[64];
+
+    epi_restoreMdbResponse(&leng, ResData);
+    // 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: lastResult   1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)
+    // DB3: nr of received (payload) data bytes (apart from ACK, can be 0....34)
+    // DB4...DB39: rec.data (payload)
+    *fromDevice=ResData[0];
+    *lastRequest=ResData[1];
+    *responseLength=ResData[3];
+    tslib_strcpy(&ResData[4], responseBuffer, ResData[3]);
+    return ResData[2];
+}
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// --------------------------------------------- Coin Checker -----------------------------------
+// ----------------------------------------------------------------------------------------------------------
+
+void hwapi::emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const
+{
+    // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
+    // tokenChannel 0...31: if this signal comes from emp then a token was inserted
+    // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)
+
+    uint8_t myBuf[64], ii, pp;
+    uint16_t uitmp=coinAcceptance;
+
+    tslib_strclr(myBuf, 0, 64);
+    myBuf[0]=uint8_t (uitmp);
+    uitmp>>=8;
+    myBuf[1]=uint8_t (uitmp);
+    myBuf[2]=tokenChannel;
+    pp=3;
+    for (ii=0; ii<16; ii++)
+    {
+        uitmp=coinDenomination[ii];
+        myBuf[pp]=uint8_t(uitmp);
+        uitmp>>=8;
+        myBuf[pp+1]=uint8_t(uitmp);
+        pp+=2;
+    }
+
+    epi_store64ByteSendData(35, myBuf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_EMP_SETT);
+
+}
+
+void hwapi::emp_pollingOnOff(uint8_t on) const
+{
+    // on: 1=start polling the coin accepter  0=stop
+    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_POLL, on,0,0,0);
+
+}
+
+void hwapi::emp_startCoinAcceptance(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STARPPAY, 0,0,0,0);
+
+}
+
+void hwapi::emp_stopCoinAcceptance(void) const
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STOPPAY, 0,0,0,0);
+
+}
+
+
+
+void hwapi::emp_getAllParameters(struct T_emp *emp) const
+{
+    uint8_t leng, data[66], ii, pp;
+    epi_restoreEmpSettings(&leng, data);    // expected length = 64 byte
+
+    // get 64 bytes about EMP: see h-file
+
+    emp->gotSetup   = data[0];
+    emp->state      = data[1];
+    emp->shaft      = data[2];
+    emp->countryCode= uchar2uint(data[4], data[3]);
+    emp->scale      = data[5];
+    emp->decimals   = data[6];
+    for (ii=0; ii<16; ii++)
+        emp->coinValues[ii] = data[7+ii];
+    emp->coinAccept = uchar2uint(data[24], data[23]);
+    emp->tokenChannel = data[25];
+    emp->pollingRunning = data[26];
+    emp->paymentRunning = data[27];
+
+    pp=28;
+    for (ii=0; ii<16; ii++)
+    {
+        emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]);
+        pp+=2;
+    }
+    emp->routing= uchar2uint(data[61], data[60]);
+
+}
+
+/*
+static bool    emp_newCoin;
+static uint8_t emp_newCoinSignal;
+static uint16_t emp_newCoinValue;
+static uint8_t emp_newCoinError;
+
+uint8_t hwapi::emp_chkIfCoinInserted(void)
+{
+    // retval: 1=got coin 0xFF=emp reported an error  0=got nothing
+    //          comes only one time after each coin, vaslues are stored
+    uint8_t leng, data[8];
+
+    epi_restoreEmpCoinSignal(&leng, data);
+        // 5 byte per inserted coin:
+        //      data[0]:   1=got coin, data set valid
+        //      data[1]:   emp-signal of last inserted coin
+        //      data[2]:   emp-error or warning
+        //      data[3,4]: emp-value of last inserted coin 3=low byte
+
+    //epi_clearEmpCoinSignal();
+
+    if (data[0]>0)
+    {
+        emp_newCoin=data[0];  // anything came in, coin or error or both
+
+        if (data[0] & 0x80)
+        {
+            emp_newCoinError=data[4];
+        }
+        if (data[0] &0x0F)
+        {
+            emp_newCoinSignal=data[1];
+            emp_newCoinValue=uchar2uint(data[3], data[2]);
+        }
+        return emp_newCoin;
+    }
+    return 0;
+
+}
+
+uint8_t hwapi::emp_getInsertedCoinSignal(void)
+{
+    uint8_t uctmp=emp_newCoinSignal;
+    emp_newCoinSignal=0;    // return only once
+    return uctmp;
+
+}
+
+
+uint16_t hwapi::emp_getInsertedCoinValue(void)
+{
+    uint16_t uitmp=emp_newCoinValue;
+    emp_newCoinValue=0;    // return only once
+    return uitmp;
+}
+
+uint8_t hwapi::emp_getCoinError(void)
+{
+    uint8_t uctmp=emp_newCoinError;
+    emp_newCoinError=0;    // return only once
+    return uctmp;
+}
+*/
+
+uint8_t hwapi::emp_chkIfCoinInserted(void) const
+{
+    // retval: 0...16 coins left in FIFO
+    return epi_isNewCoinLeft();
+}
+
+
+void hwapi::emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const
+{
+
+    epi_restoreEmpCoinSignal(valid, signal, error, value);
+}
+
+uint8_t hwapi::emp_giveLastCoin(uint16_t *value, uint8_t *signal) const
+{
+    // retval: 0: NO coin stored  1: valid coin  2: got wrong coin or coin denied
+    // value: if retval1: value of the coin if reval=2: error number
+    // signal: channel nr reported from checker
+
+    uint8_t valid, chan, error;
+    uint16_t wert;
+
+    epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert);
+
+    if (valid && error==0xFF )
+    {
+        *value=wert;
+        *signal=chan;
+        return 1;
+    }
+
+    if (valid && error<0xFF )
+    {
+        *value=error;
+        *signal=chan;   // normally 0, but sometimes we get both
+        return 2;
+    }
+    return 0;
+}
+
+uint8_t hwapi::emp_returnLastCoin(uint16_t *value, uint8_t *signal) const
+{
+    // use this for coin changer
+
+    uint8_t valid, chan, error;
+    uint16_t wert;
+
+    epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert);
+
+    if (error)
+    {
+        *value=0;
+        *signal=error;
+        return 0;
+    }
+    *value=wert;
+    *signal=chan;
+    return valid;
+}
+
+// ----------------------------------------------------------------------------------------------------------
+// --------------------------------------------- Bill Validator -----------------------------------
+// ----------------------------------------------------------------------------------------------------------
+/*
+// Coin checker and changer mdb4.2 / section 5
+// Level 2 Commands  (predefined device msg acc. mdb manual and auto-poll)
+uint8_t hwapi::mdb_bill_startPolling(bool on)
+{
+    // send ether one command (from list below)
+    // or a poll command in the proper polling grid (e.g. every 100ms)
+    epi_storeConfig08(mdbPollBills,on);
+    //sendWRcmd_setSendCommand0(SENDDIRCMD_WR_CONF_08);
+    return 0;
+}
+
+// the following functions tell the DC to send a mdb command to any mdb slave
+// in opposite to mdb_sendData() the exact telegrams don't have to be formed here, DC does it.
+uint8_t hwapi::mdb_bill_reset()
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 1, 0, 0, 0);
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_setup()
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 2, 0, 0, 0);
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_security(uint16_t secLevel)
+{
+
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 3, uint8_t(secLevel), uint8_t(secLevel>>8), 0);
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_pollManually(void)
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 4, 0, 0, 0);
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable)
+{
+
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillType,
+                        uint8_t(billEnable), uint8_t(billEnable>>8),
+                        uint8_t(escrowEnable), uint8_t(escrowEnable>>8));
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_escrow(uint8_t action)
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 5, action, 0, 0);
+
+    return 0;
+}
+
+uint16_t hwapi::mdb_bill_stacker(void)
+{
+    sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 6, 0, 0, 0);
+
+    return 0;
+}
+
+uint8_t hwapi::mdb_bill_expansion(uint8_t subCmd, uint8_t send[32])
+{
+    uint8_t sendbuf[34], nn;
+
+    // 1) insert subCmd into buffer
+    for (nn=0; nn<32; nn++)
+        sendbuf[nn+1]=send[nn];
+    sendbuf[0]=subCmd;
+    sendbuf[33]=0;
+    epi_storeMdbSendData(34, sendbuf);
+    sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_BillExp);
+    return 0;
+}
+
+
+uint8_t hwapi::mdb_bill_gotPollResponse(void)
+{
+    // 0: no response    1: got ACK    2: got NAK    3 got ACK with additional data
+    return epi_getMdbResponse();       // request only once, then epi_getMdbRecLength()==0
+
+}
+
+
+uint8_t hwapi::mdb_bill_getDataLen(void)
+{
+    // return nr of byte received from any mdb device
+    return epi_getMdbRecLength();
+}
+
+uint8_t hwapi::mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize)
+{
+    uint8_t len, buf[64], LL;
+    len=epi_getMdbRecLength();
+    epi_restoreMdbRecData(buf);       // request only once, then epi_getMdbRecLength()==0
+    (maxBufferSize<len)?LL=maxBufferSize:LL=len;
+    for (uint8_t nn=0; nn<LL; nn++ )
+        mdb_data[nn]=buf[nn];
+    return 0;   // OK
+}
+
+*/
+
+
+// ----------------------------------------------------------------------------------------------------------
+// --------------------------------------------- MODEM ------------------------------------------------------
+// ----------------------------------------------------------------------------------------------------------
+/*
+uint8_t hwapi::mod_getHwState(struct Tmod_hw_state *mod_hw_state)
+{
+    mod_hw_state->powerRdBk=epi_restoreReadDIs(DIBYTE0, RB_VGSM);
+    if (epi_cntchk_swRs1toModem())
+        mod_hw_state->rsSwOk=1;
+    else
+        mod_hw_state->rsSwOk=0;
+
+    mod_hw_state->rsDrvOk=epi_cntchk_enabDrv01();   // can never be false
+    mod_hw_state->HwState=false;
+    mod_hw_state->CommState=false;
+    mod_hw_state->gotAnswer=false;
+
+    return 0;
+}
+
+
+uint8_t hwapi::mod_setCondition(uint16_t chgCmd)
+{
+    // e.g. change to state registered, sleep, open, off....
+    return uint8_t(chgCmd);
+}
+
+uint16_t hwapi::mod_getCondition(void)
+{
+    // e.g. now socket open
+
+    return 0;
+}
+
+bool    hwapi::mod_sendBufferFree(void)
+{
+    // sending allowed (before writing) and sending finished (after writing)
+
+    return 0;
+}
+
+void    hwapi::mod_wantReadData(uint16_t nrOfData)
+{
+    // start reading
+    nrOfData=0;
+
+}
+
+uint8_t hwapi::mod_sendDataBlk(uint16_t len, uint8_t *buf)
+{
+    len=buf[0];
+    return uint8_t(len);
+}
+
+uint16_t hwapi::mod_gotData(void)
+{
+    // return nr of received bytes
+
+    return 0;
+}
+
+uint8_t hwapi::mod_loadDataBlk(uint16_t len, uint8_t *buf)
+{
+    len=buf[0];
+    return uint8_t(len);
+
+
+}
+
+uint8_t hwapi::mod_setupSerial(struct TserialParams serialParameter)
+{
+    // Baudrate and so on...
+    return 0;
+}
+
+uint8_t hwapi::mod_getCurrentSerialSettings(struct TserialParams *serialParameter)
+{
+    // Baudrate and so on...
+
+    return 0;
+}
+*/
+
+
+
+
+
+
+
+
+
+
+// neu, 25.8.21
+
+
+
+
+QString hwapi::dc_getTxt4RsDiagWin(void) const
+{
+    return epi_getTxt4RsDiagWin();
+}
+
+void hwapi::dc_clrTxt4RsDiagWin(void) const
+{
+    epi_clrTxt4RsDiagWin();
+}
+
+QString hwapi::dc_get2ndTxt4RsDiagWin(void) const
+{
+    return epi_get2ndTxt4RsDiagWin();
+}
+
+void hwapi::dc_clr2ndTxt4RsDiagWin(void) const
+{
+    epi_clr2ndTxt4RsDiagWin();
+}
+
+QString hwapi::dc_getTxt4HsStateLine(void) const
+{
+    // Crash!
+    return epi_getTxt4HsStateLine();
+}
+
+void hwapi::dc_clrTxt4HsStateLine(void) const
+{
+    epi_clrTxt4HsStateLine();
+}
+
+
+QString hwapi::dc_getTxt4masterStateLine(void) const
+{
+    return epi_getTxt4masterStateLine();
+}
+
+void hwapi::dc_clrTxt4masterStateLine(void) const
+{
+    epi_clrTxt4masterStateLine();
+}
+
+QString hwapi::dc_getTxt4resultStateLine(void) const
+{
+    return epi_getTxt4resultStateLine();
+}
+
+void hwapi::dc_clrTxt4resultStateLine(void) const
+{
+    epi_clrTxt4resultStateLine();
+}
+
+QString hwapi::dc_getdataStateLine(void) const
+{
+    return epi_getTxt4dataStateLine();
+}
+
+void hwapi::dc_clrTxt4dataStateLine(void) const
+{
+    epi_clrTxt4dataStateLine();
+}
+
+
+QString hwapi::dc_getdatifLine(void) const
+{
+    return epi_getTxt4datifLine();
+}
+
+void hwapi::dc_clrTxt4datifLine(void) const
+{
+    epi_clrTxt4datifLine();
+}
+
+
+
+
+// using DC2 Bootloader
+
+void hwapi::bl_iniChain(void) const
+{
+    dcBL_iniChain();
+}
+
+
+bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const
+{
+    return dcBL_importBinFile(readBinFile, fileSize, withDispl);
+}
+
+uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const
+{
+    return dcBL_activatBootloader(sendData);
+}
+
+uint8_t hwapi::bl_startChain(void) const
+{
+    return dcBL_startChain();
+}
+
+uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const
+{
+    // minimum size of sendData-buffer: 5byte  retval: length
+
+    return dcBL_readBLversion(sendData);
+}
+
+uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const
+{
+    // minimum size of sendData-buffer: 5byte  retval: length
+    return dcBL_readFWversion(sendData);
+
+}
+
+uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const
+{
+// 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
+
+    return dcBL_prepareDC_BLcmd(Cmd, SendDataLength, sendData, outBuf);
+
+}
+
+uint8_t hwapi::bl_exitBL(uint8_t *sendData) const
+{
+    // minimum size of sendData-buffer: 5byte  retval: length
+    return dcBL_exitBL(sendData);
+}
+
+void hwapi::led_switchLedIllumination(uint8_t on) const
+{
+    if (on)
+    {
+
+    }
+
+}
+
+
+
+// neu, 25.3.23
+
+// ------------------------------------------------------------------------------------
+// 27.3.2023: Use Device-Controller's Bootloader to send hex-file
+// ------------------------------------------------------------------------------------
+
+void hwapi::bl_rebootDC(void) const
+{
+    uint8_t len, buf[20];
+
+    len=dcBL_restartDC(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+}
+
+void hwapi::bl_startBL(void) const {
+    uint8_t len, buf[20];
+    memset(buf, 0x00, sizeof(buf));
+
+    len=dcBL_activatBootloader(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+}
+
+bool hwapi::bl_checkBL(void) const
+{
+    uint8_t len, buf[20];
+
+    //len=dcBL_readBLversion(buf);
+    len=dcBL_readFWversion(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+
+    return (len > 0);
+}
+
+bool hwapi::bl_isUp(void) const
+{
+    uint8_t receivedData[160];
+    uint8_t LL;
+
+    memset(receivedData, 0x00, sizeof(receivedData));
+
+    LL=epi_getRawRecLength();
+    if (LL>0)
+    {
+        epi_getRawReceivedData(receivedData);
+        //epi_clrRawReceivedString();
+
+        //qDebug() << " *** got " << LL << " data bytes from BL: " <<
+         //   receivedData[0] << " " << receivedData[1] << " " << receivedData[2] << " " <<
+         //   receivedData[3] << " " << receivedData[4] << " " << receivedData[5] << " ";
+
+        // response to "readFWversion"
+        if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 &&
+            receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176)
+        {
+            dcBL_iniLoading();
+            return true;
+        }
+        // response to "start BL"
+        if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 &&
+            receivedData[3]==223 && receivedData[4] ==131 )
+        {
+            dcBL_iniLoading();
+            return true;
+        }
+
+    }
+    return false;
+}
+
+
+void hwapi::bl_sendAddress(u_int16_t blockNumber) const
+{
+    // send start address, nr of 64byte-block, start with 0
+    // will be sent only for folling block-numbers:
+    // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
+    uint32_t dcBL_BlkCtr=(uint32_t)blockNumber;
+    uint8_t  len, buf[20];
+
+    tslib_strclr(buf, 0, 20);
+    if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
+    {
+        dcBL_BlkCtr*=64;
+        len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf);   // make command string
+            // uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData)
+            // minimum size of sendData-buffer: 13byte    retval: length (9...13)
+        sendWRcmd_setSendBlock160(len, buf);        // send command to BL
+    }
+}
+
+uint8_t hwapi::bl_wasSendingAddOK(void) const
+{
+    // return val: 0: no response by now  1:error  10: OK
+
+    return dcBL_sendSuccess(0x21);
+    // return val: 0: no response by now  1:error  10: OK
+        // lastCommand=0x21 for sendAddr or 0x22 for send data
+
+}
+
+void hwapi::bl_openBinary(void) const
+{
+
+    dcBL_loadBinary(0);
+}
+
+void hwapi::bl_sendDataBlock(uint8_t length, u_int8_t *buffer) const
+{
+    // send 64 byte from bin file
+    uint8_t LL=length, sendBuf[80], sendLen;
+    if (LL>64) LL=64;
+
+    tslib_strclr(sendBuf,0,80);
+/*  hier ist alles richtig
+    qDebug() << "bl_sendDataBlock "<<LL<< " bytes: " << buffer[0] << " " << buffer[1] << " "
+     << buffer[2] << " " << buffer[3] << " " << buffer[4] << " " << buffer[5] << " "
+     << buffer[6] << " " << buffer[7] << " " << buffer[8] << " " << buffer[9] << " "
+    << buffer[61] << " " << buffer[62] << " " << buffer[63] << " " << buffer[64] << " "
+    << buffer[65] << " " << buffer[66] << " " << buffer[67] << " " << buffer[68] << " ";
+*/
+    sendLen=dcBL_prepareDC_BLcmd(0x22, LL, buffer, sendBuf);   // pack into protocol frame
+/*
+    qDebug() << "bl_sendDataBlock "<<sendLen<< " bytes: " << sendBuf[0] << " " << sendBuf[1] << " "
+     << sendBuf[2] << " " << sendBuf[3] << " " << sendBuf[4] << " " << sendBuf[5] << " "
+    << sendBuf[6] << " " << sendBuf[68] << " " << sendBuf[69] << " " << sendBuf[70] << " "
+    << sendBuf[71] << " " << sendBuf[72] << " " << sendBuf[73] << " " << sendBuf[74] << " ";
+*/
+    sendWRcmd_setSendBlock160(sendLen, sendBuf);                  // send 140 bytes
+    delay(100);
+}
+
+void hwapi::bl_sendLastBlock(void) const
+{
+    uint8_t len, buf[20];
+
+    len=dcBL_writeLastPage(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+}
+
+uint8_t hwapi::bl_wasSendingDataOK(void) const
+{
+    // return val: 0: no response by now  1:error  10: OK
+
+    return dcBL_sendSuccess(0x22);
+    // return val: 0: no response by now  1:error  10: OK
+        // lastCommand=0x21 for sendAddr or 0x22 for send data
+
+}
+
+void hwapi::bl_stopBL(void) const
+{
+    uint8_t len, buf[20];
+
+    len=dcBL_exitBL(buf);
+    sendWRcmd_setSendBlock160(len, buf);
+
+}
+/*
+bool hwapi::bl_isDiagAvailable(void) const
+{
+
+    return dcBL_checkForText();
+}
+
+
+QString hwapi::dc_getDiagText(void) const
+{
+    return dcBL_readText();    // read from 0...9 (oldest first)
+}
+*/
+
+/*
+// geht noch nicht //////
+void hwapi::bl_startSending(void) const
+{
+
+    dcBL_startLoading();
+}
+
+
+void hwapi::bl_sendFile(void) const
+{
+//qDebug()<<" HWAPI_BL_CYCL_ISrunning ";
+
+    dcBL_sendHexfile();
+
+}
+*/
+
+
+// ------------------------------------------------------------------------------------
+// 6.4.2023: new functions for coin collection and printing
+//            some new system functions
+// ------------------------------------------------------------------------------------
+
+// use:
+// 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 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 hwapi::rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const
+{
+    // return true if successful. could fail if more the 8 commands are waiting
+
+    uint8_t temp[66];
+    bool   b_ret;
+    /* in interfaces.h:
+    struct Trtc_DateTime
+    {
+       uint8_t rtc_hour;
+       uint8_t rtc_min;
+       uint8_t rtc_sec;
+       uint8_t rtc_dayOfMonth;
+       uint8_t rtc_month;
+       uint8_t rtc_year;
+       uint8_t rtc_dayOfWeek;
+    };
+    */
+    tslib_strclr(temp,0,66);
+    temp[0]= DateTime->rtc_hour;
+    temp[1]= DateTime->rtc_min;
+    temp[2]= DateTime->rtc_sec;
+    temp[3]= 20;
+    temp[4]= DateTime->rtc_year;
+    temp[5]= DateTime->rtc_month;
+    temp[6]= DateTime->rtc_dayOfMonth;
+    temp[7]= DateTime->rtc_dayOfWeek;
+    b_ret=longFDcmd_set(20,0,0,8,temp);
+    return b_ret;
+}
+
+bool hwapi::rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const
+{
+    epi_restoreExtendedTime(leng, data);
+    return true;
+
+/*
+     buf[0]=GlobTime.Hours;
+    buf[1]=GlobTime.Min;
+    buf[2]=GlobTime.Sec;
+    buf[3]=GlobTime.Year;
+    buf[4]=GlobTime.Month;
+    buf[5]=GlobTime.Day;
+    buf[6]=GlobTime.DOW;
+    buf[7]=' ';                   // immer auf 32bit auffüllen sonst Speicherproblem beim Master!
+    uitmp=GlobTime.MinOfDay;
+    buf[8]=swl_getOneByteFromUint(uitmp, 0);
+    buf[9]=swl_getOneByteFromUint(uitmp, 1);
+    buf[10]=' ';
+    buf[11]=' ';
+    ultmp=GlobTime.SecOfDay;
+    buf[12]=swl_getOneByteFromUlong(ultmp, 0);
+    buf[13]=swl_getOneByteFromUlong(ultmp, 1);
+    buf[14]=swl_getOneByteFromUlong(ultmp, 2);
+    buf[15]=swl_getOneByteFromUlong(ultmp, 3);
+
+    buf[16]=swl_isLeap(GlobTime.Year);
+    buf[17]=swl_getNextLeapYear(GlobTime.Year);
+    buf[18]=swl_getLastLeapYear(GlobTime.Year);
+    buf[19]=swl_hoursOfThisWeek(GlobTime.DOW, GlobTime.Hours);
+
+    uitmp=swl_minutesOfThisWeek(GlobTime.DOW, GlobTime.Hours, GlobTime.Min);
+    buf[20]=swl_getOneByteFromUint(uitmp, 0);    // 0=low byte   1=high byte
+    buf[21]=swl_getOneByteFromUint(uitmp, 1);
+
+    uitmp=swl_hoursOfThisMonth(GlobTime.Day, GlobTime.Hours);
+    buf[22]=swl_getOneByteFromUint(uitmp, 0);
+    buf[23]=swl_getOneByteFromUint(uitmp, 1);
+
+    uitmp=swl_minutesOfThisMonth(GlobTime.Day, GlobTime.Hours, GlobTime.Min);
+    buf[24]=swl_getOneByteFromUint(uitmp, 0);
+    buf[25]=swl_getOneByteFromUint(uitmp, 1);
+
+    uitmp=swl_GetDaysOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day);
+    buf[26]=swl_getOneByteFromUint(uitmp, 0);
+    buf[27]=swl_getOneByteFromUint(uitmp, 1);
+
+    uitmp=swl_GetHoursOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours);
+    buf[28]=swl_getOneByteFromUint(uitmp, 0);
+    buf[29]=swl_getOneByteFromUint(uitmp, 1);
+    buf[30]=0;
+    buf[31]=0;
+    ultmp= swl_GetMinutesOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day,
+                                GlobTime.Hours, GlobTime.Min);
+    buf[32]=swl_getOneByteFromUlong(ultmp, 0);
+    buf[33]=swl_getOneByteFromUlong(ultmp, 1);
+    buf[34]=swl_getOneByteFromUlong(ultmp, 2);
+    buf[35]=swl_getOneByteFromUlong(ultmp, 3);
+
+    buf[36]=rtc_getSqwaveSettings();
+    buf[37]=0;
+    buf[38]=0;
+    buf[39]=0;
+
+    ultmp= 0;       // Minutes of the Millenium
+    buf[40]=swl_getOneByteFromUlong(ultmp, 0);
+    buf[41]=swl_getOneByteFromUlong(ultmp, 1);
+    buf[42]=swl_getOneByteFromUlong(ultmp, 2);
+    buf[43]=swl_getOneByteFromUlong(ultmp, 3);
+
+    dc2prot_setReadData(44, buf);
+
+ */
+
+}
+
+bool hwapi::sys_runCompleteTest(void) const
+{
+    // warning: lasts 20s in one pace
+    return sendFDcmd_set(149, 0,0, 0,0,0,0);
+}
+
+bool hwapi::sys_ready4sending(void) const
+{
+    // return true if a Json-file can be sent
+
+    // check free memory
+    uint8_t frei=FDLONG_STACKDEPTH - check4FDlongCmd();
+        // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte
+        // in check4FDlongCmd() steht wieviele Plaetze bereits belegt sind
+        // frei gibt also die Anzahl freier 64byte Bloecke zurueck
+        // das Json-File hat max 800 byte = 13 bloecke
+    if (frei<16)        // Puffer muss ganz leer sein! nicht dass was durcheinander kommt
+        return false;
+    return true;
+}
+
+bool hwapi::sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const
+{
+    // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
+    //      nrOfTemplate=1...32 if kindOfFile==6
+    //      content = content of the Json file, max 800byte ascii signs
+    // file is 0-terminated
+    // return false if sending is not possible, wait a second
+
+    uint8_t dateiArt, NummDesTempl;
+    uint8_t inhaltOfJson[802], temp[66];
+    uint16_t dateiLang, uitmp;
+    uint8_t nrOfBlocks;
+    uint8_t frei, bn=0;
+
+    dateiArt=kindOfFile;
+    NummDesTempl=nrOfTemplate;
+    tslib_strclr(inhaltOfJson,0,801);
+    dateiLang=tslib_strlen(content);
+    if (dateiLang>800) dateiLang=800;
+    tslib_strcpy(content, inhaltOfJson, dateiLang); // enthaelt genaue Laenge, Rest =0
+    nrOfBlocks=dateiLang/64;
+    if (dateiLang%64>0)
+        nrOfBlocks++;
+    dateiLang=nrOfBlocks;
+    dateiLang<<=6;  // auf volle 64byte aufgerundet
+
+    // check free memory
+    frei=FDLONG_STACKDEPTH - check4FDlongCmd();
+        // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte
+        // in check4FDlongCmd() steht wieviele Plaetze bereits belegt sind
+        // frei gibt also die Anzahl freier 64byte Bloecke zurueck
+        // das Json-File hat max 800 byte = 13 bloecke
+    if (frei<16)        // Puffer muss ganz leer sein! nicht dass was durcheinander kommt
+        return false;
+
+    // Start- und Stop auch als langes Kommando schicken
+    // PROBLEM: wuerden sie in einem anderen Batch gespeichert (short command stack),
+    //          dann kann die Reihenfolge nicht gewaehrleistet werden
+    //          Das Startkommando muss sicher zuerst kommen
+    //          Das Abschlusskommando muss sicher zuletzt kommen
+
+    tslib_strclr(temp,0,65);
+    temp[0]=dateiArt;
+    temp[1]=NummDesTempl;
+    longFDcmd_set(30, 0,0, 2,temp);      // sende "Starte-file-DL"
+    uitmp=0; bn=0;
+    do
+    {
+        biox_CopyBlock(inhaltOfJson, uitmp, temp, 0, 64);
+        longFDcmd_set(31,0, bn++, 64, temp);
+        uitmp += 64;
+        // uitmp<<=6;
+    } while(uitmp < dateiLang);
+
+    longFDcmd_set(32, 0,0, 0,temp);       // Abschluss
+
+    return true;
+}
+
+//char prn_dynPrnVal[8][8];
+bool hwapi::prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const
+// dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string
+//            like:     char prn_dynPrnVal[8][8];
+// return true if sending, false if cmd-stack is full
+{
+
+    uint8_t  temp[66];
+
+
+    tslib_strcpy(dynPrnVal, temp, 64); // Vorsicht, kann \0en enthalten
+    return longFDcmd_set(33,0,0, 64, temp);
+
+}
+
+bool hwapi::prn_printTemplate(uint8_t nrOftemplate) const
+    // print one of the templates loaded by Json prior
+    // nr = 1..32
+{
+    // return true if sending, false if cmd-stack is full
+    return sendFDcmd_set(152, 0,0, nrOftemplate,0,0,0);
+}
+
+void hwapi::log_getHoldAccountNumbers(uint32_t *accNr ) const
+    // returns all acc nrs of the backuped vault records
+    // use: uint32_t backupedAccNumbers[8]
+{
+    Q_UNUSED(accNr);
+}
+
+
+
+bool hwapi::log_selectVaultRecord(uint16_t accountNr ) const
+{
+    // return true if sending, false if cmd-stack is full
+    uint8_t dat1, dat2;
+
+    dat1=uint2uchar(accountNr, LOWBYTE);
+    dat2=uint2uchar(accountNr, HIGHBYTE);
+    return sendFDcmd_set(153, 0,0, dat1,dat2,0,0);
+
+}
+
+
+//request, isAvailable
+void hwapi::log_getVaultRecord(struct T_vaultRecord *retVR) const
+    // which was selected by: log_selectVaultRecord()
+    // to be forwarded to Ismas
+{
+    Q_UNUSED(retVR);
+}
+
+bool hwapi::prn_printAccountReceipt(void) const
+{
+    return sendFDcmd_set(154, 0,0, 0,0,0,0);
+}
+
+bool hwapi::prn_printTestTicket(void) const
+{
+    // return true if sending to DC OK, false if cmd-stack is full
+    return sendFDcmd_set(157, 0,0, 0,0,0,0);
+
+}
+
+bool hwapi::cash_startPayment(uint16_t amount) const
+{
+    uint8_t dat1, dat2;
+
+    epi_clearCurrentPayment();
+    dat1=uint2uchar(amount, LOWBYTE);
+    dat2=uint2uchar(amount, HIGHBYTE);
+    return sendFDcmd_set(155, 0,0, dat1,dat2,0,0);
+
+}
+
+uint32_t hwapi::getInsertedAmount(void) const
+{
+    return epi_CurrentPaymentGetAmount();
+}
+
+uint16_t hwapi::getLastInsertedCoin(void) const
+{
+    return epi_CurrentPaymentGetLastCoin();
+}
+
+bool hwapi::getAllInsertedCoins(uint16_t *types, uint16_t *values) const
+{
+    // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64
+    return epi_CurrentPaymentGetAllCoins(types, values);
+
+}
+
+
+bool hwapi::cash_cancelPayment(void) const
+    // and return coins
+{
+    // DB1: 1=encash    2=cancel & return coins
+    //      3=stop and keep coins in escrow
+    return sendFDcmd_set(156, 0,0, 2,0,0,0);
+}
+bool hwapi::cash_stopPayment(void) const
+    // and keep coins in escrow
+{
+    // DB1: 1=encash    2=cancel & return coins
+    //      3=stop and keep coins in escrow
+    return sendFDcmd_set(156, 0,0, 3,0,0,0);
+
+}
+// after ticket/goods issue:
+bool hwapi::vend_success(void) const
+    // conclude payment process, encash all inserted coins to vault. Printing was successful
+    // if possible return change
+{
+    // DB1: 1=encash    2=cancel & return coins
+    //      3=stop and keep coins in escrow
+    return sendFDcmd_set(156, 0,0, 1,0,0,0);
+
+}
+bool hwapi::vend_failed(void) const
+    // conclude payment process and return all inserted coins
+{
+    // DB1: 1=encash    2=cancel & return coins
+    //      3=stop and keep coins in escrow
+    return sendFDcmd_set(156, 0,0, 2,0,0,0);
+
+}
+
+
+
+
+
+
+uint8_t hwapi::mif_getCardType(QString cardholder) const
+    // return 1,2,3,4 = upper, lower access card, printer test, coin test
+    // cardholder: 7byte Name-String
+{
+    Q_UNUSED(cardholder);
+    return 0; // to satisfy compiler
+}
+
+uint64_t hwapi::sys_getWakeSource(void) const
+{
+    // retval: 6 bytes, bit coded, 1=event keeps DC awake
+     return epi_getWakeSources();
+}
+
+//void hwapi::sys_getDeviceConditions(struct T_moduleCondition *devCond) const
+void hwapi::sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const
+{
+    //uint8_t leng, data[66];
+    epi_restoreDeviceConditions(leng, data);
+}
+
+//void hwapi::sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const
+void hwapi::sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const
+{
+    epi_restoreDeviceConditions(leng, data);
+}
+
+