#ifndef INTERFACE_H
#define INTERFACE_H

#include <QtPlugin>



struct T_emp
{

   // Fixdata from EMP:
   uint8_t shaft;      // = changer level
   uint16_t countryCode;
   uint8_t scale;
   uint8_t decimals;
   uint8_t coinValues[16];
   uint16_t routing;

   // Master specs:
   uint8_t gotSetup;       // 1: got specifications from master   0: no specs
   uint16_t coinAccept;    //  bit 0 = coin1  bit H=accept
   uint8_t tokenChannel;
   uint16_t denomination[16];

   // dynamic:
   uint8_t state;      // step counter of EMP (electronic coin checker) FSM (finite state machine):
                       // 0=Emp & Bus power off,  1=powered, poll off    2=polling on
                       // 3=device responded, requesting status
                       // 4=waiting for status     5=have status,
                       // 6: IDLE,  have paramters from master, polling running, ready for payment
                       //          Master can stop/start polling and acceptance
                       // 7: end of transaction,  polling on, accept off, reporting coins, (wait for last coin)
                       // 8: transaction running, polling on, acceptance on, reporting coins,

   uint8_t pollingRunning;
   uint8_t paymentRunning;

};

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;
};

struct Tprn_hw_state
{
    // hardware (IO's)
    bool powerRdBk;     // prn pwr is on
    bool rsSwOk;        // serial switch (printer or modem) is set to printer
    bool rsDrvOk;       // RS232 converter for PTU, Printer and Modem in on

    bool ReadyLine;     // HW signal from printer showing ready
    bool inIdle;        // powered and free from errors
    bool paperNearEnd;  // paper roll runs out
    bool noPaper;
    bool ErrorTemp;
    bool HeadOpen;
    bool cutterJam;
    bool noResponse;    // printer is not connected, cable broken, wrong baudrate
    bool badResponse;
};

 struct Tprn_currentSettings
{
    uint8_t currFont;
    uint8_t currSize;
    uint8_t currHeigth;
    uint8_t currWidth;
    bool    nowBold;
    bool    nowInvers;
    bool    nowUnderlined;
    uint8_t currDensity;
    uint8_t currSpeed;
    bool    nowAligned;
};

 struct T_dynDat
{
    uint8_t licensePlate[8];
    uint8_t vendingPrice[8];
    uint8_t parkingEnd[8];
    uint8_t currentTime[8];
    uint8_t currentDate[8];
    uint8_t dynDat5[8];
    uint8_t dynDat6[8];
    uint8_t dynDat7[8];
};


struct T_vaultRecord
{

    // Kassenbeleg (Abrechnungsdatensatz = Kassenwechsel-Datensatz)
        char startbuffer[4];		// Psa>  // never move or change this 1st entry
        uint16_t AccountingNumber;
        uint16_t CUNU;
        uint16_t MANU;
        uint16_t resint1;
        //uint16_t resint2;

        char label1buffer[4];	 // tim>
        uint8_t year;
        uint8_t month;
        uint8_t dom;
        uint8_t hour;
        uint8_t min;
        uint8_t sec;
        uint8_t DoW;
        uint8_t reschar3;

        char label2buffer[4];	// abs>
        uint32_t AbsIncome1;
        uint32_t AbsReserve;
        uint32_t AbsNrOfCuts;

//16
        char label3buffer[4];	// mw >

        // Verkauf, Tür zu:
        uint32_t VKcoinsInserted[16];		// nur für Wechsler, soviel wurde eingeworfen
        uint32_t VKcoinsReturned[6];		// nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
//88

        // Service, Tür offen:
        uint16_t ServCoinsInserted[16];		// nur für Wechsler, soviel wurde eingeworfen
        uint16_t ServCoinsReturned[6];		// nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
        uint16_t resint3;
        uint16_t resint4;
        uint16_t currentTubeContent[6];		//  nur für Wechsler, aktueller Füllstand
        uint16_t resint5;
        uint16_t resint6;
// 56

        char label4buffer[4];	// box>
        uint16_t coinsInVault[16];
        uint16_t billsInStacker[8];
// 48

        char label5buffer[4];	// val>
        // actually constant unless exchange rate is changed
        uint16_t coinDenomination[16];	// 5..50000 (z.B. 2? sind in Ungarn 760Ft)
        uint16_t billDenom[8];
        uint16_t tubeDenom[6];
        uint16_t exchangeRate;
        uint16_t resint9;

// 64

        char endofblock[4];	// end>

// 316 byte Block im Speicher

};

struct T_moduleCondition
{
        // store conditon of all system components, hold in RAM
        // 0 means unknown, not yet tested/used
        // 1 means OK
        // 50..99	= HINT / Notification
        // 100..150	= WARNING
        // 200..250	= ERROR

        uint8_t	ram;
        uint8_t	intEe;
        uint8_t	extEe;

        uint8_t	rtc;				// 1: time/date OK   100: time not plausible  200: hardware error
        uint8_t	boardHw;
        uint8_t	printer;
        uint8_t	modem;

        uint8_t	signal;				//		1...99
        uint8_t	regist;				// 100:not  1:reg  2:ping OK   3:gotTime
        uint8_t	mdbBus;
        uint8_t	coinChecker;		// EMP, OMP or mei-cashflow

        uint8_t	coinEscrow;
        uint8_t	mifareReader;
        uint8_t	creditTerm;
        uint8_t	coinReject;

        uint8_t	coinSafe;
        uint8_t   billSafe;
        uint8_t	voltage;			// 1:11..14V
        uint8_t   temper;

        uint8_t	poweronTest;
        uint8_t   doorState;			// 1: alles zu  200: t?r offen + bit1(S) +bit2(CB) + bit3(CB)
        uint8_t	doorWasOpened;		// 1: all doors are closed   200: any door was just opened
        uint8_t	changer;			// can only be tested by usage

        uint8_t   coinBlocker;		// can only be tested by usage
        uint8_t   billReader;			// can only be tested by usage
        uint8_t   ResetReason;
        uint8_t	allModulesChecked;

        uint8_t   alarmState;
        uint8_t   res11;
        uint8_t   res12;
        uint8_t   res13;

};

struct T_dynamicCondition
{
        char allDoorsDebounced;
        char openedAuthorized;
        uint8_t CBinDebounced;
        char upperDoor;		// 0:fehlt  1:drin
        char middleDoor;
        char lowerDoor;
        char coinBox;
        char billBox;
        char modeAbrech;
        char onAlarm;
        char nowCardTest;
        char nowPayment;
        char lastMifCardType;
        uint8_t lastSDoorState;
        uint8_t lastVDoorState;
        uint8_t lastCBstate;
        char        paymentInProgress;
        char        res1;
        uint16_t    U_Batt;
        uint16_t	Temperatur;
        uint16_t	nrCoinsInBox;
        uint32_t	amountInBox;
        uint32_t	totalTransVolume;
        uint32_t	totalNrOfVends;
        char        jsonValid_config;
        char        jsonValid_device;
        char        jsonValid_cash;
        char        jsonValid_print;
        char        jsonValid_serial;
        char        jsonValid_time;
        char        lastFileType;
// 44
        uint8_t     MifCardHolder[8];
        uint8_t     resultOfLastTemplPrint;
                    // 0: unknown or printing in progress
                    // 1: OK, doc was printed   2: error, doc was not printed
        uint8_t     lastPrinterStatus;
                    //        0: printer OK
                    //          bit0: near paper end          bit1: no paper
                    //          bit2: temperature error       bit3: error head open
                    //          bit4: paper jam in cutter
                    //          bit6: no response             bit7: serial rec. error
                    //			bit5: printer not ready
//54
};

struct T_extTime
{
    uint8_t     Hours;
    uint8_t     Min;
    uint8_t     Sec;
    uint8_t     Year;
    uint8_t     Month;
    uint8_t     Day;
    uint8_t     DOW;
    uint8_t     res1;
    uint16_t    MinOfDay;
    uint16_t    res2;
    uint32_t    SecOfDay;
    uint8_t     isLeapYear;
    uint8_t     nxtLeapYear;
    uint8_t     lastLeapYear;
    uint8_t     hoursOfThisWeek;
    uint16_t    minutesOfThisWeek;
    uint16_t    hoursOfThisMonth;
    uint16_t    daysOfThisYear;
    uint16_t    GetHoursOfYear;
    uint16_t    res3;
    uint32_t    GetMinutesOfYear;
    uint8_t     getWakeIntvSec;
    uint8_t     res4;
    uint16_t    res5;
    uint32_t    MinutesOfMillenium;

};

class hwinf
{

public:
    enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
    enum class FileTypeJson {CONFIG=1, DEVICE, CASH, SERIAL, TIME, PRINTER};

    virtual ~hwinf() {}
               
    
                                           
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    //       Use serial interface and protocol stack in Cashagent-Library
    //           Sending Output data to DeviceController DC2b
    //           Sending input requests to DC2 (single or auto-batch)
    //           Getting input data as receiver payload
    //      Furthermore the Cashagent-Library answers with status strings about sending and reading result
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const = 0;
        // Command: open serial interface
        // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
        // BaudStr: for exapmle "19200"
        // ComName: for example "COM48"
        // connect: 0, 1

    virtual bool dc_closeSerial(void) const = 0;
        // Command: close serial interface in order to save power while power down
        // or if another port must be used
        
    virtual bool dc_isPortOpen(void) const =0;
        // returns true if port open (don't send unless open. Sending to closed port will crash program)
                   
        
        
    virtual uint8_t test_serialState(void) const =0;
        // test on-board signals for the serials
        // serial drv on/off, Serial mux1, Serial mux2
    
    virtual bool test_serialIsOn(void) const =0;      
        
    virtual bool dc_updateDC(QString binFileName,
                             QString baudrate,
                             QString comPort) const = 0;
        // download binary file down into device controller

    virtual bool dc_updatePrinterTemplate(enum FileTypeJson type,
                                          QVector<int> templateIdx,
                                          QVector<QString> fnames,
                                          QString br,
                                          QString serial = QString()) const = 0;

    virtual bool dc_printTemplate(enum FileTypeJson type,
                                  QVector<int> templateIdx,
                                  QString br,
                                  QString serial = QString()) const = 0;

    virtual void dc_autoRequest(bool on)  const =0;
        // on = true:  select that all READ-Requests are sent automatically 
        // on = false: select that all READ-Requests are sent manually one by one
                    // Every input information from DC2 must be requested 
                    // ( digital and analog sensors, get time/date, get status information )

    virtual uint8_t dc_isRequestDone(void)  const =0;
        // retval:  0: request is still in progress
        //          1: answer from DC2 was OK
        //          2: wrong answer from DC2

    virtual uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad)  const =0;
        // get data back in "payLoad", max 64 byte, can be used for diagnosis
        // retval = nr of bytes received. If host buffer too small then
        // only plBufSiz bytes are copied to "payLoad"
        // plBufSiz­z=size of host buffer
                            
    virtual void dc_requTestResponse()  const =0;
        // tell DC2 to send a test-string, useful to see if cable and baudrate is OK
        
    virtual bool dc_readAnswTestResponse()  const =0;
        // retval: true: test was successful, got right response
                                                                 
    virtual uint8_t getRawRecLength(void)  const =0;
        // only needed if protocol stack in Cashagent-Library is bypassed
        
    virtual uint8_t getRawReceivedData(uint8_t *receivedData)  const =0;
        // only needed if protocol stack in Cashagent-Library is bypassed
    
    virtual QString dc_getSerialState(void)  const =0;   
        // get result of opening-command like "ttyS0 opened with 115200 8N1!
        // or error messages like "comport not available..."
        // was saved by last opening event, can be passed for 100ms
            
    virtual void dc_clrSerialStateText(void)  const =0;
        // clear above text to avoid multiple repetive displaying
        
        
    virtual QString dc_getTxt4HsStateLine(void)  const =0;  
        // return string with status of handshakes
    
    virtual void dc_clrTxt4HsStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
        
                          
    virtual QString dc_getTxt4masterStateLine(void)  const =0;  
        // returns string telling if the received packet is valid and complies protocol
        // if OK: "slave response OK"    in case of error: "wrong length received", "wrong start sign received",
        //                              "received datalen to big", "wrong data len received", "wrong crc received"    
        
    virtual void dc_clrTxt4masterStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
                           
               
    virtual QString dc_getTxt4resultStateLine(void)  const =0;   
       // returns string telling response of DC. First question: did DC get a correct request telegram?
       // and if: 2nd question did DC perform the contained output and input commands
       // if OK: "Slave OUT and IN Result: 0 0"
       // in case of error: "slave got wrong start sign" ..length"  ...crc"  ... address" 
       //                   slave does not perform and command!
       // 2nd) received telegram was OK, DC tried to perform the master commands. result
       //   result of writing data (e.g switching leds and motors, sending stuff to printer...)
       //      OUT = 0: OK   1: unknown command  2: operation not possible 
       // result of reading data (e.g. switches, voltages, accepted coins, printer status....)
       //       IN = 0: OK   1: unknown command   2: could not read due to hardware error  3: could not read because device is off  
                   
    virtual void dc_clrTxt4resultStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying

        
    virtual QString dc_getdataStateLine(void)  const =0; 
        // check if recveied input data are ok/valid
        // OK-string : "valid INdata...." with protocol details
        // not OK: string empty
    
    virtual void dc_clrTxt4dataStateLine(void)  const =0;
        // clear above text to avoid multiple repetive displaying
        
            
    virtual QString dc_getdatifLine(void)  const =0;
        // returns string with result of function dc_requTestResponse()
            // "correct" or "false"
    
    virtual void dc_clrTxt4datifLine(void)  const =0;
        // clear above text to avoid multiple repetive displaying

               
    virtual QString dc_getTxt4RsDiagWin(void)  const =0;
        // returns string to be displayed in "serial traffic" window 
        // details about sent and received protocol
                
    virtual void dc_clrTxt4RsDiagWin(void)  const =0;       
        // clear above text to avoid multiple repetive displaying
    
    virtual QString dc_get2ndTxt4RsDiagWin(void)  const =0;  
        // returns string to be displayed in "serial traffic" window 
        // details about sent and received protocol
    
    virtual void dc_clr2ndTxt4RsDiagWin(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
    
    
// 28 functions    
                       
  
                                       
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    //       DC2b internal data 
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
 

    virtual QString dc_getSerialParams(void)  const =0;
        // get DC2 serial settings (not very meaningful as they will not come if different from master settings)
        
    virtual QString dc_getHWversion(void)  const =0;
       // get DC2 hardware version
       
    virtual QString dc_getSWversion(void)  const =0;
       // get DC2 software version
       
    virtual QString dc_getState(void)  const =0;
        // get DC2 status (every OK or any error/warning? )
                                                
    
    // UID - unique number, different in every DC
    virtual void     dc_getUID8byte(uint8_t *buf8byteUid)  const =0;
            // get 8 single bytes in buffer    
            
    virtual QString  dc_getUIDstr()  const =0;
            // get as string                            
        
    virtual uint64_t dc_getUIDnumber(void)  const =0;
            // get UID as one long number

    // Analog values:
    virtual uint32_t dc_getTemperature(void)  const =0;       
        // in Sax-Format 0...400 (0=-50,0°C    100=0,0°C    141=20,5°C    400=150,0°C)
    
    virtual QString  dc_getTemperaturStr(void)  const =0;
        // as string like "-12,5°C"
        
    virtual uint32_t dc_getVoltage(void)  const =0;           
        // as value in mV,  0...65,535V
        
    virtual QString  dc_getVoltagStr(void)  const =0;
        // as string in mV
        
    virtual bool dc_mainFuseIsOk(void) const=0;
        // true if 12V fuse is OK
        // false: fuse blown, DC will continue working but no 12V device can be used!
                                                                              
    virtual void dc_setWakeFrequency(uint8_t period)  const =0;
        // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
        // change wake signal period to 1...64s

    virtual void dc_OrderToReset(void)  const =0;
        // want DC2 to reset (in order to start Bootloader)



    // 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

    virtual void request_DC2serialConfig()  const =0;
            // read-request can be sent manually by this function, not needed if auto-request is on

    virtual void request_DC2_HWversion() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_SWversion() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_condition() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_UID() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on


    virtual void request_DC2_analogues() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_digitalInputs() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_digitalOutputs() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on

// 22

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // using DC2 Bootloader   
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf)  const =0;
        // send without protocol frame, needed for the DC bootloader

    virtual void bl_iniChain(void)  const =0;                             
    
    virtual bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl)  const =0;   
    
    virtual uint8_t bl_activatBootloader(uint8_t *sendData)  const =0; 
    
    virtual uint8_t bl_startChain(void)  const =0;     
    
    virtual uint8_t bl_readBLversion(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length 
        
    virtual uint8_t bl_readFWversion(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length

    virtual uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf)  const =0;
        // 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

    virtual uint8_t bl_exitBL(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length




// 9

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // get Time and Date from DC2b (contains a buffered real time clock) valid for about three days without power
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime)  const =0;

    virtual uint8_t rtc_setDateTime(void)  const =0;
        // synch DC2 with PC or PTU system time and date

    virtual void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss)  const =0;
        // get time directly

    virtual void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd)  const =0;
        // get date directly

    virtual uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday)  const =0;
        // dow=day of week, 1=monday...7
        // minOfToday: 0=midnight...1439= 23:59
        // secOfToday: 0=midnight...86399= 23:59:59

    virtual bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear)  const =0;
        // retval true: this year is leap year

    virtual bool rtc_isLeapYear()  const =0;

    virtual void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek)  const =0;
        // 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

    virtual void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth)  const =0;
        // 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

    virtual void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear)  const =0;
        // 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

    virtual QString rtc_getTimStr(void)  const =0;
    virtual QString rtc_getDatStr(void)  const =0;
    virtual QString rtc_getTimDatStr(void)  const =0;
    

                              
    
    virtual void request_DC2_TimeAndDate() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    
    
    
// 14

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // PTU, Master
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void ptu_switchWake(bool WAKEACTIVE)  const =0;

    virtual bool ptu_WakeINisActive(void)  const =0;

    virtual bool ptu_WakeOutIsOn(void) const =0;

    virtual void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
                            uint8_t kindOfMifareReader, uint8_t suppressSleep,
                            uint8_t kindOfModem,        uint8_t kindOfCredit        ) const =0;
        // 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)


    virtual void request_ReadbackDeviceSettings() const =0;

    virtual void readback_DeviceSettings(uint8_t *length, uint8_t *data) const =0;
/*
            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);

*/

    virtual void sendMachineID(uint16_t customerNr, uint16_t machineNr,
                              uint16_t borough, uint16_t zone,
                              uint16_t alias,   char *location) const =0;

    virtual void request_ReadbackMachineID() const =0;

    virtual void readback_machineIDdata(uint8_t *length, uint8_t *data) const =0;
    // 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
    // 12.4.23TS still the same

   
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Printer
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    


    virtual void prn_switchPower(bool on)  const =0;

    virtual bool prn_isPrinterPowerOn(void)  const =0;

    virtual uint8_t prn_PrnFuseIsOk(void) const=0;
     //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off

    virtual bool prn_readyINisActive(void)  const =0;
                       
    virtual  uint8_t cash_getLowPaperSensor(void) const=0;
        // 0: Sensor sees paper 1: no paper 99: off

    // the following device state requests are deployed only if device is powered up:
    virtual void request_PrinterHwState() const =0;
    virtual void request_PrinterCurrentFonts() const =0;
    virtual void request_PrinterStateComplete() const =0;
        
    virtual bool test_serialMux1isSetToPrinter(void) const =0;

    // read printer condition and settings

    virtual uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const =0;
        // 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"

    virtual bool prn_isUpAndReady(void) const =0;
        // true: printer is powered, serial is ok, no error, printer is connected and resonding

    virtual void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const =0;


    // send Commands to printer:

    virtual void prn_sendText(QByteArray *buf) const =0;
        // up to 1280 bytes

    virtual void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const =0;
        // send three byte through to printer, see printers manual

    virtual void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const =0;
        // send four byte through to printer, see printers manual


    virtual void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const =0;
        // 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

    virtual void prn_movePaper(uint8_t wayInMm, uint8_t direction) const =0;
        //direction: 1=forward 2=backward
        //
    virtual void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const =0;
        // 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

    virtual void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const =0;
        // bold: 0/1
        // invers: 0/1
        // underlined: 0/1

    virtual void prn_cut(uint8_t kindof) const =0;
        // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut)

    virtual void prn_newLine(uint8_t nrOfLines) const =0;

    virtual void prn_printCompleteFontTable(void) const =0;

    virtual void prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const =0;
        // 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

    virtual void prn_sendQRdata(QByteArray *buf) const =0;
        // maximal 150 alphanummeric bytes

    virtual void prn_printQRcode(void) const =0;
        // QRcode may have 1...150 alphanummeric data, must be transfered in advance


    virtual void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const =0;
        // 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!!)

    virtual void pri_startTicketDesign(void) const =0;
        // 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

    virtual int pri_TD_getCurrentSize(void) const =0;
        // retval: 0...1278

    virtual bool pri_TD_addText(QByteArray text) const =0;
        // example: pri_TD_addText("Hello") const =0;
        // example: pri_TD_addText(tempStr) const =0;
        // retval: true=ok false=too long, buffer full

    virtual bool pri_TD_addValue(int val) const =0;
        // +/- 0...2^(31)

    virtual bool pri_TD_addNewLine(void) const =0;

    virtual bool pri_TD_addSign(char sign) const =0;
        // example: '.'   ' '   0x20 'W' '$'

    virtual bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const =0;
        // 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

    */

    virtual char prn_clearDocument(uint8_t documentNumber) const =0;
        // clear memory buffer for ONE document
        // function takes a second! don't send right before "store doc"

    virtual bool prn_store_Document(uint8_t documentNumber ) const =0;
        // 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

    virtual bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const =0;


// 36

    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Mifare Card Reader
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    
    virtual void mif_readerOn(bool on)  const =0;

    virtual bool mif_cardIsAttached(void)  const =0;
    virtual bool mif_isMifarePowerOn(void)  const =0;

    virtual void request_MifareReaderState() const =0;
    virtual void request_MifareCardType() const =0;
    virtual void request_MifareAtbType() const =0;    
    virtual void request_MifareID() const =0;
    virtual void request_MifareData(uint8_t dataBlockNumber) const =0;
    //virtual void request_MifareData() const =0;

        // dataBlockNumber must be 0....11, returns 64byte of data


    virtual bool test_serialMux2isSetToMifare(void) const =0;

    virtual void mif_creatAtbCard(uint8_t cardType) const =0;

    /* 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"
    byte16: 1=card is present   0:not
    17: 0
    18: card type reported from reader
    19: 1=allowed card type 0=not
    20: card size: 1 or 4 (dec) = card size
    21: LengthOfUID: 4 or 7 (dec) (byte)
    22: UID 8 byte in hex
    byte 30: sector logged: 0
    byte 31: current sector: 0
    byte 32: result, always 0
    */
    virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0;
        // retval 0=OK 1=error host buffer too small

    virtual bool mif_readerIsOK(void) const =0;

    virtual bool mif_cardAttached(void) const =0;

    virtual uint8_t mif_readResult(void) const =0;
        // result: 0: unknown or still in progress
        //         1: card read successful
        //         2: reading error

    //virtual void mif_clearDataBuffer(void) const =0;
 
    virtual QString mif_cardUID(void) const =0;
        // returns string with 8 byte

    //virtual bool mif_isBlockAvailable(uint8_t blkNr) const =0;
        //blkNr=0...11
        
    //virtual uint32_t mif_getAvailableDataBlocks(void) const =0;
        // bit0=1 if block 0 = valid ...up to ... bit 11=1 if block 11=read

    virtual uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const =0;

    virtual QString mif_getCardDataStr(uint8_t blockNumber) const =0;
        // with blockNumber=0...11

    // read mifare data independant from blocks
    //virtual uint16_t mif_getNrOfAvailableDataBytes(void) const =0;

    //virtual bool mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) const =0;

    //virtual bool mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) const =0;

    //virtual QString mif_getCardDataStr(bool useHexFormat, char seperator) const =0;

// 16
    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Credit Card Terminal
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    
    virtual void credit_switchPower(bool on)  const =0;
        // the same as modem power

    virtual bool cred_isCreditPowerOn(void)  const =0;

    virtual bool test_serialMux2isSetToCredit(void) const =0;

    virtual void credit_switchWake(bool WAKEACTIVE)  const =0;

// 4
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Modem
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
            
    virtual void mod_switchPower(bool on) const=0;

    virtual bool mod_isGsmPowerOn(void)  const =0;

    virtual bool test_serialMux1isSetToModem(void) const =0;

    virtual void mod_switchWake(bool WAKEACTIVE) const=0;

// 2

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // MDB Bus
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void mdb_switchPower(bool on)  const =0;
    virtual void mdb_switchWake(bool WAKEACTIVE)  const =0;

    virtual bool mdb_WakeINisActive(void)  const =0;
    virtual bool mdb_testIsmdbTxDon(void)  const =0;
    virtual bool mdb_isMdbPowerOn(void)  const =0;

    virtual void request_MDB_Status() const =0;
    virtual void request_MDB_lastResponse() const =0;

    virtual bool test_getDO_mdbRXtst(void) const =0;
        //  readback digital outputs of connected devices
        //  these functions are not needed for normal operation
        //  but can be used to test and verify conditions

    virtual void mdb_sendBusReset(void) const =0;

    virtual void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const =0;
        // 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

    virtual void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const =0;
        // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
        // same as mdb_sendCommand, just with data

    virtual bool mdb_busIsReadyToWork() const =0;

    virtual bool mdb_deviceVoltageOK() const =0;

    virtual bool mdb_busVoltageOk() const =0;

    virtual uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
                                      uint8_t *responseLength, uint8_t *responseBuffer) const =0;
        // 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)


// 15
    

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Coin Changer, Checker (EMP)
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void request_EMP_allParameters() const =0;  
    
    virtual void request_EMP_lastCoin() const =0;
   
    virtual uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const =0;
        // use for changer


    // ---------------------------------- Electronic Coin Validator EMP -----------------------------------------
 
    virtual void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0;
        // 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...)

    virtual void emp_pollingOnOff(uint8_t on) const =0;

    virtual void emp_startCoinAcceptance(void) const =0;

    virtual void emp_stopCoinAcceptance(void) const =0;

    virtual void emp_getAllParameters(struct T_emp *emp) const =0;
        // see struct in hwapi.h
        // usage example:
        //      hwapi   *HWaccess const =0;
        //      HWaccess = new hwapi() const =0;
        //      struct T_emp   myEmp const =0;
        //      HWaccess->emp_getAllParameters(&myEmp) const =0;
        //          readval=myEmp.pollingRunning const =0;

    virtual uint8_t emp_chkIfCoinInserted(void) const =0;
        // retval: 0...16 coins left in FIFO

    virtual void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const =0;
        // 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( ):
    virtual uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const =0;
        // 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

// 11
                           
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Coin blocker, Coin Escrow, Coin reject
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
                                
    virtual void shut_move(bool open)  const =0;
    virtual void esc_moveFlaps(uint8_t flap )  const =0;
        // 0: close both  1: open take-flap   2: open return

    virtual void coin_switchRejectMotor(uint8_t dir) const =0;
    virtual bool coid_isAttached(void)  const =0;
    virtual bool coin_escrowIsOpen(void)  const =0;
    virtual  bool cash_getRejectMotorHomePos(void) const=0;


    virtual bool coin_shutterIsOpen(void) const =0;
    virtual bool coin_shutterTestOutput(void) const =0;

    virtual uint8_t coin_escrowFlapOpened(void) const =0;
        // retval: 1:return flap is open   2:take flap is open    0:closed

    virtual void shut_openOnce(void) const =0;
        // and close automatic after shutter time

    virtual void shut_openForCoin(bool start) const =0;
        // open flap if coin is attached
        // once process is started it runs until stop command

    virtual void shut_sendOpeningTime(uint16_t timeIn_ms ) const =0;
        // after this time without retrigger the flap is closed

    virtual void esc_takeMoney(void) const =0;
        // and close automatically after escrow time (1s)

    virtual void esc_returnMoney(void) const =0;
        // and close automatically after escrow time (1s)

     virtual void coin_rejectCoins(void) const =0;

// 15

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // MDB Bill evaluator
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

              
    
    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // doors, locks, cashboxes
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void lock_switchContactPower(bool on)  const =0;
                                    
    virtual bool door_isContactPowerOn(void)  const =0;
                                    
    virtual uint8_t door_getLocks(void)  const =0;
        // retval bit0: upper lever is up   (=open)
        //        bit1: upper lever is down (=locked)
        //        bit2: lower lever is up
        //        bit3: lower lever is down (=locked)
                                        
    virtual bool door_upperDoorIsLocked(void)  const =0;

    virtual bool door_upperDoorIsUnlocked(void)  const =0;
                           
    virtual uint8_t lock_switchUpperLock(uint8_t dir)  const =0;
        // dir 0=off 1=up 2=down         
        // move lock until stop cmd (0)
            
    virtual uint8_t lock_openUpperDoor(void) const =0;
    // Locks stops automatically at end switch or by timeout

    virtual uint8_t lock_closeUpperDoor(void) const =0;
    // Locks stops automatically at end switch or by timeout
                   
    virtual uint8_t door_getSwitches(void)  const =0;
        // retval:  bit0: upper door  1: low door  2:vault door
                  
    virtual bool    door_isUpperDoorOpen(void)  const =0;        
    

    virtual bool door_lowerDoorIsLocked(void)  const =0;

    virtual bool door_lowerDoorIsUnlocked(void)  const =0;
        
    virtual uint8_t lock_switchLowerLock(uint8_t dir)  const =0;
        // dir 0=off 1=up 2=down
        // move lock until stop cmd (0)
                       
    virtual uint8_t lock_getDO_motors(void) const =0;
        // bit0: upper lock forward    bit 1 backward
        // bit2: lower lock forward    bit 3 backward

    virtual uint8_t lock_openLowerDoor(void) const =0;
        // there's no closing function as Lock always makes one complete cycle and can be locked again immed.

    virtual uint8_t lock_closeLowerDoor(void) const =0;

    virtual bool    door_isLowerDoorOpen(void)  const =0;
                                                     
    virtual uint8_t vault_getSwitches(void)  const =0;
        // retval bit0: cash box,  bit 1: bill box
        
    virtual bool    vault_isVaultDoorOpen(void)  const =0;
                          
    virtual void lock_switchVaultDoor(void)  const =0;
    
    virtual bool    vault_isCoinVaultIn(void)  const =0;

    virtual bool    vault_isBillVaultIn(void)  const =0;

// 21
        

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // LEDs, Barrier, Alarm, Relais, Aux
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void led_switchLedIllumination(uint8_t on) const = 0;

    virtual void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
                  
    virtual bool led_coinIsOn(void) const =0;
        // read back digital output from DC-uC-Port
    virtual bool led_frontIsOn(void) const =0;
                          
    virtual void led_switchLedService(uint8_t on)  const =0;
    // on=1   off=0
    virtual bool led_insideIsOn(void) const =0;
            
    virtual void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_ticketIsOn(void) const =0;

    virtual void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_StartIsOn(void) const =0;

    virtual void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_pinIsOn(void) const =0;

    
    virtual void fan_switchFan(bool on)  const =0;
    virtual void alarm_switchSiren(bool on) const =0;
    virtual bool fan_isOn(void) const =0;
   
    virtual bool siren_isOn(void) const =0;
    
    virtual void bar_OpenBarrier(bool open)  const =0;       
    virtual bool bar_relayIsOn(void) const =0;

    virtual bool bar_optoIn1isOn(void)  const =0;

    virtual bool bar_optoIn2isOn(void)  const =0;

    virtual void aux_power(bool on)  const =0;
    virtual bool aux_powerIsOn(void) const =0;

    virtual void aux_setUsage(uint8_t PinDirection)  const =0;
    virtual void aux_setOutputs(uint8_t PinIsHigh)  const =0;

    virtual bool aux_isAuxPowerOn(void)  const =0;

    virtual uint8_t aux_getAuxInputs(void)  const =0;



// ------------------------------------------------------------------------------------
// 27.3.2023: Use Device-Controller's Bootloader to send hex-file
// ------------------------------------------------------------------------------------

    virtual void bl_rebootDC(void) const =0;

    virtual void bl_startBL(void) const = 0;
        // send command within 4s after DC power-on, otherwise bl is left

    virtual bool bl_checkBL(void) const = 0;
        // send command to verify if bl is up

    virtual bool bl_isUp(void) const =0;
        // return true is bl is up and running
        // also initializes "sendFile"

    virtual void bl_sendAddress(uint16_t blockNumber) const=0;
        // send start address, nr of 64byte-block, start with 0
        // will be sent only for following block-numbers:
        // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
        // for other addresses nothing happens

    virtual uint8_t bl_wasSendingAddOK(void) const=0;
    // return val: 0: no response by now  1:error  10: OK

    virtual void bl_openBinary(void) const=0;
        // to be used within CashAgent, momentary not processed

    virtual void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const=0;
    // send 64 byte from bin file

    virtual void bl_sendLastBlock(void) const=0;
    // send this command after all data are transfered

    virtual uint8_t bl_wasSendingDataOK(void) const=0;
    // return val: 0: no response by now  1:error  10: OK

    virtual void bl_stopBL(void) const=0;
        // leave BL and start (the new) application

    //virtual bool bl_isDiagAvailable(void) const=0;

    //virtual QString dc_getDiagText(void) const=0;


    // Komplett-schreib Funktion, noch nicht getestet
    // Nachteil: keine Rückmeldung wie lang's noch dauert
    //virtual void bl_startSending(void) const=0;
        // call once after BL is working and file is loaded
    //virtual void bl_sendFile(void) const=0;
        // call cyclic while loading bin-file to bootloader




// ------------------------------------------------------------------------------------
// 6.4.2023: new functions for coin collection and printing
//            some new system functions
// ------------------------------------------------------------------------------------

    virtual bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const=0;
        // return true if sending, false if cmd-stack is full

    virtual bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const=0;
/*
     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);

 */

    virtual bool rtc_getExtendedTime(struct T_extTime *exTime) const=0;

    virtual bool sys_runCompleteTest(void) const=0;
        // warning: lasts 20s in one pace
        // return true if sending, false if cmd-stack is full

    virtual bool sys_ready4sending(void) const=0;
    // return true if a Json-file can be sent

    virtual bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const=0;
        // 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 true if sending, false if cmd-stack is full

    virtual bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const=0;
        // 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

    virtual bool prn_printTemplate(uint8_t nrOftemplate) const=0;
        // print one of the templates loaded by Json prior
        // nr = 1..32
        // return true if sending, false if cmd-stack is full

    virtual void log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const=0;
        // returns all acc nrs of the backuped vault records
        // use: uint16_t backupedAccNumbers[8]

    virtual bool log_selectVaultRecord(uint16_t accountNr ) const=0;
        // return true if sending, false if cmd-stack is full
        // and trigger transfer

    virtual bool log_chkIfVaultRecordAvailable(void) const=0;
        // return true if completly received

    virtual bool log_getVaultRecord(struct T_vaultRecord *retVR) const=0;
        // which was selected by: log_selectVaultRecord()
        // to be forwarded to Ismas

    virtual bool prn_printAccountReceipt(void) const=0;
        // return true if sending to DC OK, false if cmd-stack is full

    virtual bool prn_printTestTicket(void) const=0;
        // return true if sending to DC OK, false if cmd-stack is full

    virtual bool cash_startPayment(uint32_t amount) const=0;
        // 17.4.23TS: extended to 32bit

    virtual uint32_t getInsertedAmount(void) const=0;

    virtual uint16_t getLastInsertedCoin(void) const=0;

    virtual bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const=0;
        // all inserted coins (max 64) since "cash_startPayment"

    virtual bool cash_cancelPayment(void) const=0;
        // and return coins

    virtual bool cash_stopPayment(void) const=0;
        // and keep coins in escrow

    // after ticket/goods issue:
    virtual bool vend_success(void) const=0;
        // conclude payment process, encash all inserted coins to vault. Printing was successful
        // if possible return change

    virtual bool vend_failed(void) const=0;
        // conclude payment process and return all inserted coins


    virtual uint8_t mif_getCardType(QString *cardholder) const=0;
        // return 1,2,3,4 = upper, lower access card, printer test, coin test
        // cardholder: 7byte Name-String

    virtual uint64_t sys_getWakeSource(void) const =0;
        // retval: 6 bytes, bit coded, 1=event keeps DC awake

    virtual void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const=0;
    /*

    outBuf[0]=modCond.ram;
    outBuf[1]=modCond.intEe;
    outBuf[2]=modCond.extEe;
    outBuf[3]=modCond.rtc;
    outBuf[4]=modCond.boardHw;
    outBuf[5]=modCond.printer;
    outBuf[6]=modCond.modem;
    outBuf[7]=modCond.signal;
    outBuf[8]=modCond.regist;
    outBuf[9]=modCond.mdbBus;
    outBuf[10]=modCond.coinChecker;
    outBuf[11]=modCond.coinEscrow;
    outBuf[12]=modCond.mifareReader;
    outBuf[13]=modCond.creditTerm;
    outBuf[14]=modCond.coinReject;
    outBuf[15]=modCond.coinSafe;
    outBuf[16]=modCond.billSafe;
    outBuf[17]=modCond.voltage;
    outBuf[18]=modCond.temper;
    outBuf[19]=modCond.poweronTest;
    outBuf[20]=modCond.doorState;
    outBuf[21]=modCond.doorWasOpened;
    outBuf[22]=modCond.changer;
    outBuf[23]=modCond.coinBlocker;
    outBuf[24]=modCond.billReader;
    outBuf[25]=modCond.ResetReason;
    outBuf[26]=modCond.allModulesChecked;
    outBuf[27]=modCond.alarmState;
    outBuf[28]=0;
    outBuf[29]=0;

     */

    virtual void sys_getDeviceConditions(struct T_moduleCondition *devCond) const=0;
    virtual void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const=0;
/*

    outBuf[pBuf++]=dynCond.allDoorsDebounced;
    outBuf[pBuf++]=dynCond.openedAuthorized;
    outBuf[pBuf++]=dynCond.CBinDebounced;
    outBuf[pBuf++]=dynCond.upperDoor;

    outBuf[pBuf++]=dynCond.middleDoor;
    outBuf[pBuf++]=dynCond.lowerDoor;
    outBuf[pBuf++]=dynCond.coinBox;
    outBuf[pBuf++]=dynCond.billBox;

    outBuf[pBuf++]=dynCond.modeAbrech;
    outBuf[pBuf++]=dynCond.onAlarm;
    outBuf[pBuf++]=dynCond.nowCardTest;
    outBuf[pBuf++]=dynCond.nowPayment;

    outBuf[pBuf++]=dynCond.lastMifCardType;
    outBuf[pBuf++]=dynCond.lastSDoorState;
    outBuf[pBuf++]=dynCond.lastVDoorState;
    outBuf[pBuf++]=dynCond.lastCBstate;

    outBuf[pBuf++]=dynCond.paymentInProgress;
    outBuf[pBuf++]=0;
    uitmp=dynCond.U_Batt;
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
    uitmp=dynCond.Temperatur;
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);

    uitmp=dynCond.nrCoinsInBox;	// send seperate also
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);

    ultmp=dynCond.amountInBox;	// send seperate also
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);

    ultmp=dynCond.totalTransVolume;
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);

    ultmp=dynCond.totalNrOfVends;
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);
// 36
    outBuf[pBuf++]=dynCond.jsonValid_config;
    outBuf[pBuf++]=dynCond.jsonValid_device;
    outBuf[pBuf++]=dynCond.jsonValid_cash;
    outBuf[pBuf++]=dynCond.jsonValid_print;
    outBuf[pBuf++]=dynCond.jsonValid_serial;
    outBuf[pBuf++]=dynCond.jsonValid_time;
    outBuf[pBuf++]=dynCond.lastFileType;
    outBuf[pBuf++]=0;

*/

    virtual void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const=0;

    // content of Cashbox
    virtual uint32_t cash_getAmountInVault(void) const=0;

    virtual uint16_t cash_getNrCoinsInVault(void) const=0;


    virtual uint8_t prn_getPrintResult() const=0;

    // in case of print-error get detailed error:
    virtual uint8_t prn_getCurrentPrinterState() const=0;
        //        0: printer OK
        //          bit0: near paper end          bit1: no paper
        //          bit2: temperature error       bit3: error head open
        //          bit4: paper jam in cutter
        //          bit6: no response             bit7: serial rec. error
        //			bit5: printer not ready

signals:
    virtual void hwapi_templatePrintFinished_OK(void) const=0;
    virtual void hwapi_templatePrintFinished_Err(void) const=0;
    virtual void hwapi_gotNewCoin(void) const=0;
    virtual void hwapi_vendStopByMax(void) const=0;
    virtual void hwapi_vendStopByPushbutton(void) const=0;

};


// 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
// 14.04.2023: V3.4 new features extended: sys_getDynMachineConditions, sys_getDeviceConditions and
//                    rtc_getExtendedTime return struct in addition. New function to select and get VaultRecord
//

//#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"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.4"
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.5"



Q_DECLARE_INTERFACE(hwinf, HWINF_iid)


#endif