#include "datIf.h"
#include "sendWRcmd.h"
#include "controlBus.h"
#include "storeINdata.h"
#include <QDebug>

// called from MainWindow()


#define     DATIF_MAXCMDS        16
static uint8_t dif_dataStep;
static uint8_t dif_scanStep, RDBLKNR;


static uint8_t datif_OutCmdpara1, datif_OutCmdpara2, datif_OutCmdpara3, datif_OutCmdpara4;
static uint16_t datif_OutCmdpara5;
static uint32_t datif_OutCmdpara6;
static uint8_t cycl_running;

//static bool     datif_DCdataValid;

T_datif::T_datif(QWidget *parent) : QMainWindow(parent)
{

    myDCIF = new T_prot();

    // valid data was received, storing
    connect(myDCIF, SIGNAL(framerecieved()), this, SLOT(StoredRecData()));

    // new, 9.11.20 data for DC-bootloader received not matchind Pprot
    //connect(myDCIF, SIGNAL(rawDataRecieved()), this, SLOT(BLdataRecData()));

    // cyclic transmission of INPUT-Requests
    datif_trigger = new QTimer();
    connect(datif_trigger, SIGNAL(timeout()), this, SLOT(datif_cycleSend()));
    datif_trigger->setSingleShot(false);
    datif_trigger->start(10);     // in ms, 80 gut, default 100   50....200

    // passing Signal through
    //connect(myDCIF, SIGNAL(framerecieved()), this, SLOT( ResponseRecieved() ));

    datif_OutCmdpara1=0;
    datif_OutCmdpara2=0;
    datif_OutCmdpara3=0;
    datif_OutCmdpara4=0;
    dif_dataStep=1;

    dif_scanStep=0;
    selectedSlaveAddr=FIX_SLAVE_ADDR;
    cycl_running=0;
    //datif_DCdataValid=0;
    gpi_storeDcDataValid(0);
}

void T_datif::resetChain(void)
{
   dif_scanStep=0;
}

char T_datif::datif_cycleSend()
{
    // cyclic transmission of INPUT-Requests
    // call cyclic to send next request every 100ms, then wait for response before sending again!!!
    uint16_t nxtAsCmd;
    uint8_t  dataSendBuf[160], dataBufLen, dbl, who;
    static uint8_t BlockCounter;

    uint8_t nextWrCmd, nextRdCmd, blockNum, dat1, dat2, dat3, dat4;
    uint8_t length, data[66];
    bool b_ret;

    if (cycl_running)
    {
        // request is still running, wait for response before next sending
        datif_trigger->stop();
        datif_trigger->start(10);
        cycl_running++;
        if (cycl_running>10)
            cycl_running=0;
        return 0;
    }
    if (myDCIF->isPortOpen())
    {
        #ifdef USEHANDSHAKES
        if (myDCIF->isSerialFree())
        #endif
        {
            // new, from 11.4.23: direkt access to fastDevice Interface
                // always use this three functions to send data:
                //void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t  WrDatLen, uint8_t *data);
                //void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr);
                //void myDCIF->setUserWriteData(uint16_t WriteCmd);
                //void myDCIF->setUserWrite1DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val);
                //void myDCIF->setUserWrite2DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1);

                //void myDCIF->setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr, uint16_t reserv);
                //void myDCIF->setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr);
                //void myDCIF->setUserReadData( uint16_t ReadCmd);

                //void myDCIF->sendUserData(uint16_t slaveAdr);

            if (check4FDshortCmd())
            {
                b_ret=sendFDcmd_get(&nextWrCmd, &nextRdCmd, &blockNum, &dat1, &dat2, &dat3, &dat4);
                if (b_ret)
                {
                    data[0]=dat1; data[1]=dat2; data[2]=dat3; data[3]=dat4; data[4]=0;
                    myDCIF->setUserWriteData(nextWrCmd, blockNum, 4, data);
                    myDCIF->setUserReadData(nextRdCmd);
                    myDCIF->sendUserData(selectedSlaveAddr);
                }
            }

            if (check4FDlongCmd())
            {
                b_ret=longFDcmd_get(&nextWrCmd, &nextRdCmd, &blockNum, &length, data);
                if (b_ret)
                {
                    myDCIF->setUserWriteData(nextWrCmd, blockNum, length, data);
                    myDCIF->setUserReadData(nextRdCmd);
                    myDCIF->sendUserData(selectedSlaveAddr);
                }
            }

            // direct commands have highest prio (setting OUTPUTS)
            nxtAsCmd=sendWRcmd_getSendCommand0();       // command was stored by Gui
            if (nxtAsCmd>0)
            {
                cycl_running=1;
                // qDebug()  << "datif: send next cmd0";
                sendWRcommand(nxtAsCmd);
                send_requests(nxtAsCmd);
                sendHighLevel(nxtAsCmd);
                BlockCounter=0;
                return 0;
            }

            nxtAsCmd=sendWRcmd_getSendCommand4(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara3, &datif_OutCmdpara4);
                // command was stored by Gui
            if (nxtAsCmd>0)
            {
                cycl_running=1;
                //qDebug()  << "datif: send next cmd4";
                sendWRcommand(nxtAsCmd);
                send_requests(nxtAsCmd);
                sendHighLevel(nxtAsCmd);
                BlockCounter=0;
                return 0;
            }

            nxtAsCmd=sendWRcmd_getSendCommand8(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara5, &datif_OutCmdpara6);
                // command was stored by Gui
            if (nxtAsCmd>0)
            {
                cycl_running=1;
                //qDebug()  << "datif: send next cmd8";
                sendWRcommand(nxtAsCmd);
                send_requests(nxtAsCmd);
                sendHighLevel(nxtAsCmd);
                BlockCounter=0;
                return 0;
            }

            dbl=sendWRcmd_getSendBlock160(&dataBufLen, dataSendBuf);  // used for bootloader
            if (dbl>0)
            {
                cycl_running=1;
                //qDebug()  << "datif: sending 160 byte block, len: " << dataBufLen;
                datif_OUT_SendRandomData(dataSendBuf, dataBufLen);
                BlockCounter=0;
                return 0;
            }

            dbl=gpi_chk4remainingText();
            if (dbl>0)
            {
                cycl_running=1;
                //qDebug() << "datif: sending printer text ";
                gpi_restorePrnText(&dataSendBuf[0]);
                    // can hold 1280 byte, get next 64
                //for (uint8_t nn=0; nn<64; nn++)
                //    qDebug() << dataSendBuf[nn] << " ";


                who=gpi_getUserOfSendingTextBuffer(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara3, &datif_OutCmdpara4);

                if (who==1)
                {
                    epi_store64ByteSendData(64, dataSendBuf);   // "dueway", copy this 64 back to pi, used by datif_ send64byteOutCmd
                    datif_send64byteOutCmd(CMD2DC_PRI_PRINT_TXT, 0, 0);
                } else
                if (who==2)
                {
                    epi_store64ByteSendData(64, dataSendBuf);   // "dueway", copy this 64 back to pi, used by datif_ send64byteOutCmd
                    datif_send64byteOutCmd(CMD2DC_STOR_QR_DATA, 0, 0);
                } else
                if (who==3)
                {
                    //qDebug() << "datif: sending printer text, docnr: " <<datif_OutCmdpara1 << " blknr: " << BlockCounter;

                    datif_sendToMemory(CMD2DC_PRI_STORE_DOC, datif_OutCmdpara1, BlockCounter, dataSendBuf);
                        // "docNr" in datif_OutCmdpara1   blockNr in dbl
                    //for (uint8_t nn=0; nn<64; nn++)
                     //   qDebug() << dataSendBuf[nn] << " ";
                    BlockCounter++;
                }
                return 0;
            }


            if (gpi_isEmmisionOn())     // auto send button is pressed
            {
                //qDebug() << "auto request is on";
                sendINrequestsAutomatic();  // sendCyclicCmd();       // request all cyclic data sequential
            }
            else
                dif_scanStep=0;         // always start from beginning
        }
        #ifdef USEHANDSHAKES
        else
        {
            //qDebug()  << "last request not yet finished";
        }
        #endif
    } else
    {
        //qDebug()  << "com port not available";    // wird ununterbrochen ausgegeben
    }

    return 0;
}




// ##############################################################################
// ##############################################################################
// ##############################################################################

    // Sende Schreibbefehle die bereits vorher asynchron gespeichert wurden:
void T_datif::sendWRcommand(uint16_t nextWrCmd)
{
    // Aufruf im normalen Sendezeitraster, sende gewünschtes Einzelkommando
    //  zwischen den zyklischen aber im richtigen Raster
    //uint8_t LL;
    //uint8_t restBuf66[66];

    switch (nextWrCmd)
    {
        // basically this is the junction between asynchronous cmd and synchron sending
//        case SENDDIRCMD_TestSerial:
//            datif_sendIOrequest(0, CMD2DC_TestSerial, 0);
//            break;

        case SENDDIRCMD_setTime:
            datif_OUT_setTime();    // 0x1310            
            break;

        case SENDDIRCMD_setWakeFrequ:
            datif_sendIOrequest(CMD2DC_setWakeFrequ, 0,0);
            break;

        case SENDDIRCMD_MOVEUP_LOCK:
            datif_sendIOrequest(CMD2DC_MOV_UPLOCK, 0, 1);
            break;

        case SENDDIRCMD_MOVEDN_LOCK:
            datif_sendIOrequest(CMD2DC_MOV_DNLOCK, 0, 1);
            break;

        case SENDDIRCMD_OPENUP_DOOR:
            // Riegelleisten auf/ab bis ES
            datif_sendIOrequest(CMD2DC_UPPER_DOOR, 0, 1);
            break;

        case SENDDIRCMD_OPENDN_DOOR:
            datif_sendIOrequest(CMD2DC_LOWER_DOOR, 0, 1);
            break;

        case SENDDIRCMD_LEDILLU:
            datif_sendIOrequest(CMD2DC_LED_ILLU, CMD2DC_RdBkAllOutputs, 1);
            //                  WRITE cmd           Read Request
            //  a random request can be sent with a WRcmd, is never a disadvantage
            // but always an advantage (data are quicker actual)
            // the request does not influence the WRiting, it's independant
            break;

        case SENDDIRCMD_LEDCOIN:
            datif_sendIOrequest(CMD2DC_LED_COIN, CMD2DC_RdBkAllOutputs, 3);
            //                                                          ^ nr of params
            break;

        case SENDDIRCMD_LEDTICKET:
            datif_sendIOrequest(CMD2DC_LED_TICKET, CMD2DC_RdBkAllOutputs, 3);
            break;

        case SENDDIRCMD_LEDPAD:
            datif_sendIOrequest(CMD2DC_LED_PIN, CMD2DC_RdBkAllOutputs, 3);
            break;

        case SENDDIRCMD_LEDSTART:
            datif_sendIOrequest(CMD2DC_LED_START, CMD2DC_RdBkAllOutputs, 3);
            break;

        case SENDDIRCMD_LEDINSIDE:
            datif_sendIOrequest(CMD2DC_LED_IN, CMD2DC_RdBkAllOutputs, 1);
            break;

        case SENDDIRCMD_FAN:
            datif_sendIOrequest(CMD2DC_FAN, CMD2DC_RdBkAllOutputs, 1);
            break;
        case SENDDIRCMD_LAERM:
            datif_sendIOrequest(CMD2DC_SIREN, CMD2DC_RdBkAllOutputs, 1);
            break;
        case SENDDIRCMD_REL1:           
            datif_sendIOrequest(CMD2DC_BARRIER, CMD2DC_RdBkAllOutputs, 1);
            break;

        case SENDDIRCMD_WAKEPTU:
            datif_sendIOrequest(CMD2DC_WAKEPTU, 0, 1);
            break;

        case SENDDIRCMD_AUXPWR:
            datif_sendIOrequest(CMD2DC_SWITCHAUXPWR, CMD2DC_RdBkAllOutputs, 1);
            break;

        case SENDDIRCMD_AUXDDR:
            datif_sendIOrequest(CMD2DC_SWITCHAUXDDR, CMD2DC_RdBkAllOutputs, 1);
            break;

        case SENDDIRCMD_AUXOUT:
            datif_sendIOrequest(CMD2DC_SWITCHAUXOUT, CMD2DC_RdBkAllOutputs, 1);
            break;

        case SENDDIRCMD_PRN2_SWONOFF:
            datif_sendIOrequest(CMD2DC_PRINTERON, 0, 1);
            break;

        case SENDDIRCMD_UCONTACT_ON:
            datif_sendIOrequest(CMD2DC_UCONTACTON, 0, 1);
            break;

        case SENDDIRCMD_MIF_SWONOFF:
            datif_sendIOrequest(CMD2DC_MIFREADERON, 0, 1);      // 0x2900
            indat_storeMifarePower(datif_OutCmdpara1);
     //qDebug()<<"switching mifare on/off "<<  datif_OutCmdpara1;
        break;

        case SENDDIRCMD_MOD_SWONOFF:
            datif_sendIOrequest(CMD2DC_MOD_ON, 0, 1);
            break;
        case SENDDIRCMD_MOD_WAKE:
            datif_sendIOrequest(CMD2DC_MOD_WAK, 0, 1);
            break;


        case SENDDIRCMD_MDB_POWER:
            //qDebug()<<"switch MDB pwr" << datif_OutCmdpara1;
            datif_sendIOrequest(CMD2DC_MDB_ON, 0, 1);
            indat_storeMDBisOn(CMD2DC_MDB_ON);
            break;

        case SENDDIRCMD_MDB_RES:
            datif_sendIOrequest(CMD2DC_MDB_DORESET, 0, 1);
            break;

        case SENDDIRCMD_MDB_WAKE:
            datif_sendIOrequest(CMD2DC_MDB_SETWAK, 0, 1);
            break;

        case SENDDIRCMD_CRED_ON:
            datif_sendIOrequest(CMD2DC_CRED_ON, 0, 1);
            break;
        case SENDDIRCMD_CRED_WAKE:
            datif_sendIOrequest(CMD2DC_CRED_WAK, 0, 1);
            break;

        case SENDDIRCMD_SHUT_MOV:
            datif_sendIOrequest(CMD2DC_SHUTTER_OPEN, 0, 1);
            break;

        case SENDDIRCMD_ESCRO_MOV:
            datif_sendIOrequest(CMD2DC_ESCR_OPEN, 0, 1);
            break;

        case SENDDIR_OPENVAULT:
            datif_sendIOrequest(CMD2DC_VAULT_DOOR, 0, 0);
            //qDebug() << "Datif: send cmd open vault";
            break;

        case SENDDIR_REJMOT_ON:
            datif_sendIOrequest(CMD2DC_REJMOT_ON, 0, 1);
            //qDebug() << "Datif: send cmd reject motor";
            break;

        case SENDDIR_REJMOT_RUN:
            datif_sendIOrequest(CMD2DC_REJMOT_RUN, 0, 0);
            //qDebug() << "Datif: send cmd do coin reject";
            break;


    }

}


void T_datif::send_requests(uint16_t nextWrCmd)
{
    switch (nextWrCmd)
    {

        case SENDDIRCMD_TestSerial:
            datif_sendIOrequest(0, CMD2DC_TestSerial, 0);
            //                  ^ under no circumstances give a write cmd with the request!!!!
            break;

        case SEND_REQU_SERCONF:
            datif_sendIOrequest(0, CMD2DC_GetSerialConfig, 0);
            break;

        case SEND_REQU_HWversion:
            datif_sendIOrequest(0, CMD2DC_RdBkHWversion, 0);
            break;

        case SEND_REQU_SWversion:
            datif_sendIOrequest(0, CMD2DC_RdBkSWversion, 0);
            break;

        case SEND_REQU_CONDITION :
            datif_sendIOrequest(0, CMD2DC_RdBkDCstate, 0);
            break;

        case SEND_REQU_UID :
            datif_sendIOrequest(0, CMD2DC_RdBkUID, 0);
            break;

        case SEND_REQU_TIME :
            datif_sendIOrequest(0, CMD2DC_RdBkTime, 0);
            break;

            // includes wake frequency
        case SEND_REQU_ANALOGS :
            datif_sendIOrequest(0, CMD2DC_RdBkAnalog, 0);
            break;

        case SEND_REQU_DIG_INPUTS :
            datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            break;

        case SEND_REQU_DIG_OUTPUTS:
            datif_sendIOrequest(0, CMD2DC_RdBkAllOutputs, 0);
            break;

        case SEND_REQU_PRN_STATE:
            datif_sendIOrequest(0, CMD2DC_RdBk_PrnState, 0);
            break;

        case SEND_REQU_PRN_FONTS :
            datif_sendIOrequest(0, CMD2DC_RdBk_PrnFonts, 0);
            break;

        case SEND_REQU_PRN_ALL :
            datif_sendIOrequest(0, CMD2DC_RdBk_AllPrnData, 0);
            break;


        case SEND_REQU_MIFSTATE :
            // Type and state of reader
            datif_sendIOrequest(0, CMD2DC_RdBk_MifState, 0);
            break;

        case SEND_REQU_MIFDATA :
            // Type, UID, Header of card
            datif_sendIOrequest(0, CMD2DC_RdBk_MifData, 1); // immer nur blk 0 anfordern
        //qDebug()<<"manual requesting mif card data";
            break;

//        case SEND_REQU_MIF_ATB_TYPE :
//            // read one card sector
//            // sectors must be addressed by RD_ADD
//            datif_sendIOrequest(0, CMD2DC_RdBk_AtbCardType, 0);
//            break;

//        case SEND_REQU_MIF_DATA :
//            // read one card sector
//            // sectors must be addressed by RD_ADD
//            //datif_sendIOrequest(0, CMD2DC_RdBk_CardData, 1); ist das gleiche
//            datif_sendIOrequest(0, CMD2DC_RdBk_MifData, 1); // jeden beliebigen Block anfordern
//            break;

    case SEND_REQU_MDB_GETSTAT :
        datif_sendIOrequest(0, CMD2DC_MDB_GET_STATE, 0);
        break;

    //case SEND_REQU_MDB_GETWAK : hamma eh schoo
    //    datif_sendIOrequest(0, CMD2DC_MDB_GETWAK, 0);
    //    break;

    case SEND_REQU_MDB_GETRESP :
        datif_sendIOrequest(0, CMD2DC_MDB_GETRESP, 0);
        break;

    case SEND_REQU_EMP_GETALL :
        datif_sendIOrequest(0, CMD2DC_EMP_GET_ALL, 0);
        break;

    case SEND_REQU_EMP_GETCOIN :
        datif_sendIOrequest(0, CMD2DC_EMP_GOTCOIN, 0);
        break;

    case SEND_REQU_DEVICE_PARA :
        datif_sendIOrequest(0, CMD2DC_RDBK_DEV_PARA, 0);
        break;

    case SEND_REQU_MACINE_ID :
        datif_sendIOrequest(0, CMD2DC_RDBK_MACH_ID, 0);
        break;


    }

}


void T_datif::sendHighLevel(uint16_t nxtHLCmd)
{
    switch (nxtHLCmd)
    {

    case SENDDIRCMD_SHUTOPENBYTIME:
        //qDebug() << "open by time " << datif_OutCmdpara1 << " "<< datif_OutCmdpara2;
        datif_sendIOrequest(CMD2DC_SHUTTER_OPEN3S, 0, 1);
        break;

    case SENDDIRCMD_SHUTOPENBYCOIN:
        //qDebug() << "open by coin " << datif_OutCmdpara1 << " "<< datif_OutCmdpara2;
        datif_sendIOrequest(CMD2DC_SHUTTER_COIN, 0, 2);
        break;

    case SENDDIRCMD_ESCRO_TAKE:
        datif_sendIOrequest(CMD2DC_ESCR_TAKE, 0, 0);
        break;

    case SENDDIRCMD_ESCRO_GIVE:
        datif_sendIOrequest(CMD2DC_ESCR_RETURN, 0, 0);
        break;

    case SENDDIRCMD_MIF_ATBCREATE:
        datif_sendIOrequest(CMD2DC_ATB_CREATE, 0, 1);       // 0x2907
        break;



// yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy


    case SENDDIRCMD_MDB_SENDCMD:
        datif_sendIOrequest(CMD2DC_MDB_SENDCMD, 0, 1);
        break;

    case SENDDIRCMD_MDB_SNDMSG:
        datif_sendIOrequest(CMD2DC_MDB_SENDMSG, 0, 1);
        break;

    case SENDDIRCMD_EMP_SETT:
        //datif_sendIOrequest(CMD2DC_EMP_SET, 0, 1);
        datif_send64byteOutCmd(CMD2DC_EMP_SET,0,0);
        break;

    case SENDDIRCMD_EMP_POLL:
        datif_sendIOrequest(CMD2DC_EMP_STARTPOLL, 0, 1);
        break;

    case SENDDIRCMD_EMP_STARPPAY:
        datif_sendIOrequest(CMD2DC_EMP_STARTPAY, 0, 1);
        break;

    case SENDDIRCMD_EMP_STOPPAY:
        datif_sendIOrequest(CMD2DC_EMP_STOPPAY, 0, 1);
        break;

// yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy





    case SENDDIRCMD_PRN_SYS_CMD:
        datif_send8byteOutCmd(CMD2DC_PRI_SYS_CMD, 0);
        break;

    case SENDDIRCMD_PRN_ESC_CMD:
        datif_sendIOrequest(CMD2DC_PRI_ESC_CMD, 0, 4);
        break;

    case SENDDIRCMD_PRN_SETUP:
        // byte 0,1: speed   byte2: density    byte3: alignment    byte4: orientation
        datif_send64byteOutCmd(CMD2DC_PRI_SETUP, 0, 0);
        break;

    case SENDDIRCMD_PRN_MOVE:
        datif_sendIOrequest(CMD2DC_PRI_MOVE, 0, 2);
        break;

    case SENDDIRCMD_PRN_SETFONT:
        datif_sendIOrequest(CMD2DC_PRI_SETFONT, 0, 4);
        break;

    case SENDDIRCMD_PRN_SETLETT:
        datif_sendIOrequest(CMD2DC_PRI_SETLETTER, 0, 3);
        break;

    case SENDDIRCMD_PRN_CUT:
        datif_sendIOrequest(CMD2DC_PRI_CUT, 0, 1);
        break;

    case SENDDIRCMD_PRN_LF:
        datif_sendIOrequest(CMD2DC_PRI_LF, 0, 1);
        break;

    case SENDDIRCMD_PRN_FONTTAB:
        datif_sendIOrequest(CMD2DC_PRI_PRIFONTTABLE, 0, 0);
        break;

    case SENDDIRCMD_PRN_BC:
        datif_send64byteOutCmd(CMD2DC_PRI_BARCODE, 0, 0);
        break;

    case SENDDIRCMD_PRN_LOGO_FL:
        datif_sendIOrequest(CMD2DC_PRI_LOGOFROMFLASH, 0, 1);
        break;

    case SENDDIRCMD_PRN_DOC:
        datif_send64byteOutCmd(CMD2DC_PRI_DOCUMENT_NR, datif_OutCmdpara1, 0);
        break;

    case SENDDIRCMD_PRN_QR:
        datif_sendIOrequest(CMD2DC_PRI_QR_CODE, 0, 0);
        break;


    case SENDDIRCMD_PRN_CLEARDOC:
        datif_sendIOrequest(CMD2DC_PRI_CLEAR_DOC, 0, 1);
        break;


    case SENDDIRCMD_DEVICE_PARA:
        datif_send64byteOutCmd(CMD2DC_DEVICE_PARAM, 0, 0);
        break;


    case SENDDIRCMD_MACHINE_ID:
        datif_send64byteOutCmd(CMD2DC_SEND_MACH_ID, 0, 0);
        break;

    }

}



// ##############################################################################
// ##############################################################################
// ##############################################################################


// sende alle Befehle um die Eingangsdaten abzufragen der Reihe nach:
char T_datif::sendINrequestsAutomatic(void)
{
    //qDebug() << "send IN request " << dif_scanStep;

// one time: 105, 11,12,101,18
// cyclic:  22,23,24,27,   102,103,104,106,107,108,109,

// fehlen: 112, 113,14,17, 19,  30,31,32,33,
//          38 on request

    switch (dif_scanStep)
    {
        // first 5 items are performed only one time after startup as this data never change

        case 0:
            datif_sendIOrequest(0, CMD2DC_GetSerialConfig, 0);      // 105
            break;

        case 1:
            datif_sendIOrequest(0, CMD2DC_RdBkHWversion, 0);        // 11
            break;

        case 2:
            datif_sendIOrequest(0, CMD2DC_RdBkSWversion, 0);        // 12
            break;

        case 3:
            datif_sendIOrequest(0, CMD2DC_RdBkDCstate, 0);          // 101
            break;

        case 4:
            datif_sendIOrequest(0, CMD2DC_RdBkUID, 0);              // 18
            break;

        // repeat cyclic from here:
        case 5:
            datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);         // 102
            break;

        case 6:
            datif_sendIOrequest(0, CMD2DC_RdBkTime, 0);             // 104
            break;

        case 7:
            //datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            datif_sendIOrequest(0, 112, 0);
            break;

        case 8:
            datif_sendIOrequest(0, CMD2DC_RdBkAnalog, 0);           // 106
            break;

        case 9:
            //datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            datif_sendIOrequest(0, 113, 0);
            break;

        case 10:
            datif_sendIOrequest(0, CMD2DC_RdBkAllOutputs, 0);       // 103
            break;

        case 11:
            //datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            datif_sendIOrequest(0, 14, 0);
            break;

        case 12:
            if (indat_isPrinterOn())
                datif_sendIOrequest(0, CMD2DC_RdBk_AllPrnData, 0);      // 27
            //  datif_sendIOrequest(0, CMD2DC_RdBk_PrnState, 0);
            break;

        case 13:
            datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            break;

        case 14:
            if (indat_isMifareOn())
            {
                datif_sendIOrequest(0, CMD2DC_RdBk_MifState, 0);    // 109
                //qDebug()<<"requesting MIF reader state";
            }
            break;

        case 15:
            //datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            datif_sendIOrequest(0, 17, 0);
            break;

        case 16:
            if (indat_isMifareOn())
            {
                datif_OutCmdpara1=0;    // data block number 0 contains the Mifare-ID
                datif_sendIOrequest(0, CMD2DC_RdBk_MifData, 1);         // 24
                // qDebug()<<"automatically requesting mif card data";
                if (++RDBLKNR>11)
                    RDBLKNR=0;
                datif_OutCmdpara1=RDBLKNR;

            } break;

        case 17:
            //datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            datif_sendIOrequest(0, 19, 0);
            break;

        case 18:
            if (indat_isMdbOn())
                datif_sendIOrequest(0, CMD2DC_MDB_GET_STATE, 0);        // 107
            //else
            //    dif_scanStep=24;  unsinn
            break;

        case 19:
            datif_sendIOrequest(0, 30, 0);
            break;

        case 20:
            //if (indat_isMdbOn())
                datif_sendIOrequest(0, CMD2DC_MDB_GETRESP, 0);          // 22

            break;

        case 21:
            datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0);
            break;

        case 22:
            //if (indat_isMdbOn())    // kein eigener Schalter für EMP
                datif_sendIOrequest(0, CMD2DC_EMP_GET_ALL, 0);          // 23
            break;

        case 23:
            datif_sendIOrequest(0, 31, 0);
            break;

        case 24:
            //if (indat_isMdbOn())    // kein eigener Schalter für EMP
                datif_sendIOrequest(0, CMD2DC_EMP_GOTCOIN, 0);          // 108
            break;

        case 25:
            datif_sendIOrequest(0, 32, 0);
            break;

        case 26:
            datif_sendIOrequest(0, 33, 0);
            break;


    }

    dif_scanStep++;
    if (dif_scanStep>26)
        dif_scanStep=5;

return 0;

}


char T_datif::isPortOpen(void)
{
    return (myDCIF->isPortOpen());
}


// ##############################################################################
// ##############################################################################
// ##############################################################################
//              Empfangsdaten einsortieren
// ----------------------------------------------------------------------------------------------



void T_datif::StoredRecData()
{
    //qDebug() << "StoreRecData called";
    // call automatically by T_prot
    //if (myDCIF->ifDataReceived())
        //if (neu)
    {
        // just a wrapper as we need a retval
        // "neu" is the same as "INdataValid"
        loadRecDataFromFrame();
    }
    cycl_running=0;
}

char T_datif::loadRecDataFromFrame()
{
    // necessary data in T_prot:
    uint16_t readSource, uitmp,uit2;
    uint16_t readAddress;
    //uint8_t  pp;
    uint8_t  SlaveAdr, RdDleng;
    uint8_t  receivedData[FRAME_DATALEN];
    QString  localStr;
    uint32_t ultmp;
    //int portNr;
    bool ret;
    uint8_t uctmp;      // maxai
    char ctmp;
    static uint8_t lastResult;
    uint8_t prnResult;
    static uint32_t lastInsertedAmount;
    uint32_t newInsertedAmount;

    ret=myDCIF->getReceivedInData(&SlaveAdr, &readSource, &readAddress,  &RdDleng, receivedData);
        // retval: data valid, only one time true, true if CommandState OK and readState OK
    gpi_storeResultOfLastRequest(ret);
    if (ret==false)
    {
     //   qDebug() << "datif: rec data not valid";
        return 0;
    }

    gpi_storeRecPayLoad(RdDleng, receivedData); //  save for host (user of hwapi)

    //qDebug() << "\n datif: got valid data, rdsrc:" << readSource << "  rdadd:" << readAddress
     //        << "  rdlen:" << RdDleng;
//    qDebug("datif_recData: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ",
//            receivedData[0], receivedData[1], receivedData[2], receivedData[3],
//            receivedData[4], receivedData[5], receivedData[6], receivedData[7],
//            receivedData[8], receivedData[9], receivedData[10], receivedData[11],
//            receivedData[12], receivedData[13], receivedData[14], receivedData[15]);

    // readSource: reflects the READ Command if possible
    // readAddress: reflects the requested read/write address if slave could perform
    // lastWakeSrc: if Slave wakes master, this ist the reason for it (e.g. button pressed)
    // RdDataLength: number of bytes in receivedData

    //firstDB=receivedData[0];        // just shorter, is used very often
    //scndDB=receivedData[1];
    //thrdDB=receivedData[2];

    localStr.clear();

//    receivedData[0]='a';
//    receivedData[1]='B';
//    receivedData[2]='1';
//    receivedData[3]='-';


    for (int ii=0; ii<RdDleng; ii++)
    {
        ctmp=receivedData[ii];
        localStr.append(ctmp);
    }

    //qDebug() << "got HW version: " << localStr;
    switch (readSource) // = request command
    {
        case CMD2DC_TestSerial:    // serial line check         10
            ret=verifyLineTestresponse(RdDleng, receivedData);
            gpi_storeResult_serialTestOK(ret);
            if (ret==true)
                gpi_setTxt4datifLine("correct");
            else
                gpi_setTxt4datifLine("false");
            break;

        case CMD2DC_GetSerialConfig: // get slave's RS232 config        105
            gpi_storeSlaveSerParams(receivedData[0], receivedData[1], receivedData[2], receivedData[3]);
            //gpi_storeSlaveBusAddr(SlaveAdr);
            break;

        case CMD2DC_RdBkHWversion:                          //11
            //qDebug() << "got HW version: " << localStr;
            gpi_storeGenerals(0, localStr);
                // 0=HW   1=SW  2=State
            //gpi_storeSlaveBusAddr(SlaveAdr);
            break;

        case CMD2DC_RdBkSWversion:                          //12
            //qDebug() << "got SW version: " << localStr;
            gpi_storeGenerals(1, localStr);
            break;

        case CMD2DC_RdBkDCstate:                            //101
            //qDebug() << "got DC state " << localStr;
            //localStr[8]=0;
            gpi_storeGenerals(2, localStr);
                // 0=HW   1=SW  2=State
            break;

        case CMD2DC_RdBkUID: // getback UID in DB0....7     18
            gpi_storeUID(receivedData);
            break;

        case CMD2DC_RdBkTime: // slave returned RTC time and date       104
            // new, FastProt: 0=dayOfWeek 1=min 2=sec 3=hours 4=year 5=month 6=dayOfYear
            gpi_backupTime(receivedData, RdDleng);   // function reads 20 bytes from the buffer

            break;

        case CMD2DC_RdBkAnalog: // get ALL AIs 0...3, 4byte + 2byte each        106

        //            DB0,1: Value0=Temperature
        //            DB2,3: Value1=Voltage
        //            DB4,5: ADC0 input value 0...1023
        //            DB6,7: ADC1 input value 0...1023
            uitmp=uchar2uint(receivedData[1], receivedData[0]);
            gpi_storeMeasureValue(0, uitmp);
            uitmp=uchar2uint(receivedData[3], receivedData[2]);
            gpi_storeMeasureValue(1, uitmp);
            uitmp=uchar2uint(receivedData[5], receivedData[4]);
            gpi_storeAIs(0, uitmp);
            uitmp=uchar2uint(receivedData[7], receivedData[6]);
            gpi_storeAIs(1, uitmp);
            break;

        case CMD2DC_GetAllInputs:           //102
        /*
    // alle DI's in einen 8byte Puffer zusammenstellen, werden in einen Rutsch zum Master gesendet

    outBuf[0]:  door switches and cash boxes:
                bit 0: service
                    1: battery
                    2: vault
                    3: coin box
                    4: bill box

    outBuf[1]:  lock bar switches:
                bit 0: upper lock up
                    1: down
                bit 2: lower lock up
                    3: down
                    4: contact pwr on
                    6: opto in2

    outBuf[2]:  aux inputs:
                    2: aux2....6:aux6

    outBuf[3]:		0: ptu wake
                    1: rdBack MdbTx = 5V on if Tx low
                    2: prn ready
                    3: coin attached
                    4: Escrow
                    5: MifCardPresent
                    6: reject switch

    outBuf[4]:		0: rdMdbWake  1: Wake=Low=Active
                    1: rdBackVmif
                    2: rdBack_MdbBusPwr5V
                    3: rdBackVbar
                    4: rdBackVgsm
                    5: rdBack_CreditPwr
                    6: rdBack_Vprint
                    7: rdBack_VmdbDevice

    outBuf[5]:		0: coin Reject SwitchOn
                    1: PaperLowSensor

         */
        // qDebug()<<"datif got DIs: "<< receivedData[0] << " "
        // << receivedData[1] << " " << receivedData[2] << " "
        //<< receivedData[3] << " " << receivedData[4] << " " << receivedData[5];

            uctmp=receivedData[0];
           // qDebug()<<"datif single bits: "<< (uctmp&1) << (uctmp&2) << (uctmp&4);
            gpi_storeDI_doorSwitches(uctmp&1, uctmp&2, uctmp&4);

            gpi_storeDI_vaultSwitches(uctmp&8, uctmp&16);
            uctmp=receivedData[1];
            gpi_storeDI_lockSwitches((uctmp&3), ((uctmp>>2)&3));
            uctmp=receivedData[1];
            gpi_storeDI_contactPowerIsOn(uctmp&0x10);
            gpi_storeDI_optos((uctmp>>5)&3);
            uctmp=receivedData[2];
            gpi_storeDI_auxIn(uctmp);

            uctmp=receivedData[3];
            gpi_storeDI_ptuWake(uctmp&1);
            gpi_storeDI_readbackMdbTxD(uctmp&2);
            gpi_storeDI_prnReady(uctmp&4);
            gpi_storeDI_CoinAttach(uctmp&8);
            gpi_storeDI_CoinEscrow(uctmp&16);
            gpi_storeDI_mifareCardTapped(uctmp&32);
            gpi_storeDI_rejMot_home(uctmp&64);

            uctmp=receivedData[4];
            //gpi_storeDI_modemWake(0);    // gibt's gar nicht!
            gpi_storeDI_mbdWake(uctmp&1);
            gpi_storeDI_MifarePowerIsOn(uctmp&2);
            gpi_storeDI_AuxPowerIsOn(uctmp&8);
            gpi_storeDI_GsmPowerIsOn(uctmp&16);
            gpi_storeDI_CreditPowerIsOn(uctmp&32);
            gpi_storeDI_PrinterPowerIsOn(uctmp&64);

            //gpi_storeMdbState(uctmp&4, uctmp&128, uctmp&4);   // hat ein eigenes Cmd weiter unten!
            gpi_storeDI_MdbPowerIsOn(uctmp&128);

             gpi_storeDI_paperLow(receivedData[5]);
            break;

        case CMD2DC_RdBkAllOutputs:     //103

            /*
// alle DO's in einen 8byte Puffer zusammenstellen, werden in einen Rutsch zum Master gesendet

    outBuf[0]:  bit 0: TestMdbInput
                    1: RS1 drv enabled
                    2: RS1switch:  1=GSM    0=printer
                    3: RS2switch: H: mifare  L: credit
                    4: Vbarcode=Vaux is on

    outBuf[1]:  bit 0: coin led
                    1: 0
                    2: paper led
                    3: pinpad led
                    4: start led
                    5: service led

    outBuf[2]:  bit 0: siren
                    1: relay
                    2: ptu wake
                    3: shutter
                    4: shutter test
                    5: escrowGive
                    6: escrowTake
                    7: prn power

    outBuf[3]:  Motor 1: 0:off    1=vorwärts / öffnen     2=rückw./zu     3: beide ein
    outBuf[4]:  Motor 2: 0:off    1=vorwärts / öffnen     2=rückw./zu     3: beide ein
    */

            uctmp=receivedData[0];
            gpi_storeDO_mdbRxTst(uctmp&1);
            gpi_storeDO_auxPower(uctmp&0x10);
            gpi_storeDO_serialSwitch((uctmp>>1)&7);     // serial drv 0:on/off,   1:Serial mux1,   2:Serial mux2

            uctmp=receivedData[1];
            gpi_storeDO_ledsAndFan(uctmp);
                // bit0: coinled  1:front_illu 2: paper-led  3:pinpad-led  4:start-led  5:service-led  6:fan

            uctmp=receivedData[2];
            gpi_storeDO_sirenAndRelay(uctmp&3);         // bit0: siren  1:relay
            gpi_storeDO_ptuWake(uctmp&4);


            gpi_storeDO_coinShutter(uctmp>>3);          // bit0: Coin shutter output,    bit1: input-test-output
            gpi_storeDO_coinEscrow(uctmp>>5);   // retval: 1:return flap is open   2:take flap is open    0:closed
            gpi_storeDO_printerPwrOn(uctmp&0x80);

            uctmp=(receivedData[4] & 3);
            uctmp<<=2;
            if (receivedData[3] & 1) uctmp |=1;
            if (receivedData[3] & 2) uctmp |=2;
            gpi_storeDO_motorOutputs(uctmp);
                //   bit0: upper lock forw     bit 1 backw     bit2: lowLock forw    bit3: LL backw
            break;


    case CMD2DC_RdBk_MifState:          //109
        // get reader status and card type

        //gpi_storeMifReaderStateAndCardType(receivedData);
        gpi_storeNewMifareCard(receivedData[0], &receivedData[1]);

        break;

    case CMD2DC_RdBk_MifData:           //24
        // one block of data (64byte) comes in
        // blkNr 0...11 in "Addr"
        gpi_storeMifCardData(readAddress, receivedData);
//qDebug()<<"datif storing mif data: (adr/data) "<<readAddress<<receivedData;
        break;

    case CMD2DC_RdBk_AtbCardType:       //25
        // DC reports the type of mif-card (valid ATB card?)

        break;



    case CMD2DC_RdBk_PrnState:      // 110

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

        gpi_storePrinterState(receivedData);    // derzeit 10bytes      ( 0x2A02)
        break;

    case CMD2DC_RdBk_PrnFonts:      //  26
        //D0: font table/type
        //D1: size
        //D2: height
        //D3: width
        //D4: bold
        //D5: invers
        //D6: underlined
        //D7: density
        //D8: speed
        //D9: Alignment
        gpi_storePrinterFonts(receivedData);    // derzeit 10bytes
        break;

    case CMD2DC_RdBk_AllPrnData:      // 27
        gpi_storePrinterState(receivedData);    // derzeit 10bytes      ( 0x2A02)
        gpi_storePrinterFonts(&receivedData[10]);    // derzeit 10bytes
        /*
        qDebug()<<"printer fonts stored " <<receivedData[0]<<" "<<receivedData[1]<<" " \
               <<receivedData[2]<<" "<<receivedData[3]<<" " \
              <<receivedData[4]<<" "<<receivedData[5]<<" " \
             <<receivedData[6]<<" "<<receivedData[10]<<" " \
            <<receivedData[11]<<" "<<receivedData[18]<<" " \
           <<receivedData[19]<<" "<<receivedData[20]<<" ";
        */
        break;

    case CMD2DC_MDB_GET_STATE:      //107
        // DB0: mdb_bus_ready (switched on)
        // DB1: rdBackV12devicePower
        // DB2: rdBackV5busPwr

        //qDebug() << "got MDB state " << receivedData[0] << " " << receivedData[1] << " " << receivedData[2];
        gpi_storeMdbState(receivedData[0],receivedData[1],receivedData[2]);
        break;

    case CMD2DC_MDB_GETRESP:        //22
        // 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)
        gpi_storeMdbResponse(receivedData[2]+3, receivedData);
        break;

    case CMD2DC_EMP_GET_ALL:        //23
        //qDebug() << "got emp parameters "<< receivedData[1];
        gpi_storeEmpSettings(64, receivedData);
        break;

    case CMD2DC_EMP_GOTCOIN:        //108
        // DB0: 1=coin 0xFF=error 0=got nothing
        // DB1: last coin signal (value / scale)
        // DB2,3: last coin value
        // DB4: lastError from Emp
        gpi_storeEmpCoinSignal(receivedData[0], &receivedData[1]);
        break;
















// ab hier neu:    12.4.23

    case CMD2DC_RDBK_DEV_PARA:      //14
/*
            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);

*/
        gpi_storeRbDeviceSettings(RdDleng, receivedData);


        break;

                    // get machine parameters and location
    case CMD2DC_RDBK_MACH_ID:       //15
    case 17:
/*
            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);

*/
        gpi_storeMachineIDsettings(RdDleng, receivedData);
        break;

    case 19:        // get time and date and Extra values
/*
     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);

 */
        // speicher-fkt fehlt noch, gpi_backupTime ist nur kurz
        gpi_storeExtendedTime(RdDleng, receivedData);

        break;

    case 111:       // get square wafe settings
        gpi_backupSquareMode(receivedData[0]);
        break;

    case 112:       // get inserted amount in cent in sum
        // byte 0..3: amount just paid   4,5:last coin type  6,7: last coin value
        newInsertedAmount=uchar2ulong(receivedData[3],receivedData[2],receivedData[1],receivedData[0]);
        uitmp=uchar2uint(receivedData[5],receivedData[4]);
        uit2=uchar2uint(receivedData[7],receivedData[6]);
        gpi_storeCurrentPayment(newInsertedAmount, uitmp, uit2);
        if (newInsertedAmount != lastInsertedAmount)
        {
            emit datif_gotNewCoin();
            lastInsertedAmount=newInsertedAmount;
        }

        break;

    case 113:       // get wake source, 8byte
        gpi_storeWakeSources(receivedData);
        break;

    case 30:        // Get Devices Condition (warnings, errors)
    /*

    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;

     */
        gpi_storeDeviceConditions(RdDleng, receivedData);

        break;

    case 31:        // Get dynamic machine conditions (doors, voltage, alarm….)
/*

    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;

*/

        if (RdDleng>40)
            //datif_DCdataValid=1;    // das hier sind die wichtigsten Daten, deshalb hierrein!
            gpi_storeDcDataValid(1);

        gpi_storeDynMachineConditions(RdDleng, receivedData);

        prnResult=receivedData[52];
        if (prnResult != lastResult)
        {
            // new result
            if (prnResult==1)
            {
                emit datif_templatePrintFinished_OK();
            } else
            if (prnResult==2)
            {
                emit datif_templatePrintFinished_Err();
            }

            lastResult=prnResult;
        }

        break;

    case 32:        // Get current cash level (in vault)
                    // bytes 0..3: amount   bytes 4,5=Nr.ofCoins in vault
        ultmp=uchar2ulong(receivedData[3],receivedData[2],receivedData[1],receivedData[0]);
        uitmp=uchar2uint(receivedData[5],receivedData[4]);
        gpi_storeCBlevel(ultmp, uitmp);
        break;

    case 33:        // Get all backuped acc. Numbers
                    // 8 UINTs with acc-nr
        gpi_storeDCbackupAccNr(RdDleng, receivedData);
        break;

    case 38:        // Get stored account record backup
/*

struct T_vaultRecord
{
    UCHAR startbuffer[4];		// Psa>  // never move or change this 1st entry
    UINT AccountingNumber;
    UINT CUNU;
    UINT MANU;
    UINT resint1;
    //UINT resint2;

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

    UCHAR label2buffer[4];	// abs>
    ULONG AbsIncome1;
    ULONG AbsReserve;
    ULONG AbsNrOfCuts;

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

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

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

    UCHAR label4buffer[4];	// box>
    UINT coinsInVault[16];
    UINT billsInStacker[8];
// 48

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

// 64

    UCHAR endofblock[4];	// end>
// 316 byte Block im Speicher
*/
        // readAddress,  &RdDleng, receivedData
        gpi_storeVaultRecord(readAddress, receivedData );   // always 64byte
        break;

    }

    return 0;
}

// fehlen: 112, 113,14,17, 19,  30,31,32,33,

// subs:

// ----------------------------------------------------------------------------------------------
//                         erstelle WRITE Datensätze
// ----------------------------------------------------------------------------------------------

// always use this three functions to send data:
//void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t  WrDatLen, uint8_t *data);
//void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr);
//void myDCIF->setUserWriteData(uint16_t WriteCmd);
//void myDCIF->setUserWrite1DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val);
//void myDCIF->setUserWrite2DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1);

//void myDCIF->setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr, uint16_t reserv);
//void myDCIF->setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr);
//void myDCIF->setUserReadData( uint16_t ReadCmd);

//void myDCIF->sendUserData(uint16_t slaveAdr);

void T_datif::datif_startSending(void)
{
    // egal ob WR und RD Daten gesetzt wurden
    myDCIF->sendUserData(selectedSlaveAddr);   // starte Sendung
    gpi_startNewRequest();
    cycl_running=1;

}

// allgemeine Schreib/Lese-Funktion
void T_datif::datif_sendIOrequest(uint16_t WRcmd, uint16_t RDcmd, uint8_t nrOfWrData)
{
    uint8_t data[6];

    if (nrOfWrData>4) nrOfWrData=0;
    tslib_strclr(data,0,6);

    if (nrOfWrData>0)
        data[0]=datif_OutCmdpara1;
    if (nrOfWrData>1)
        data[1]=datif_OutCmdpara2;
    if (nrOfWrData>2)
        data[2]=datif_OutCmdpara3;
    if (nrOfWrData>3)
        data[3]=datif_OutCmdpara4;
    data[4]=0; data[5]=0;

    myDCIF->setUserWriteData(WRcmd, 0, nrOfWrData, data);
    myDCIF->setUserReadData(RDcmd);
    myDCIF->sendUserData(selectedSlaveAddr);
    cycl_running=1;

}

void T_datif::datif_send8byteOutCmd(uint16_t WRcmd, uint16_t RDcmd)
{
    uint8_t data[10];
    uint16_t uitmp;
    uint32_t ultmp;

    tslib_strclr(data,0,10);    // 8 used

    data[0]=datif_OutCmdpara1;
    data[1]=datif_OutCmdpara2;
    uitmp=datif_OutCmdpara5;
    ultmp=datif_OutCmdpara6;

    data[2]=uint8_t(uitmp);
    uitmp>>=8;
    data[3]=uint8_t(uitmp);

    data[4]=uint8_t(ultmp);
    ultmp>>=8;
    data[5]=uint8_t(ultmp);
    ultmp>>=8;
    data[6]=uint8_t(ultmp);
    ultmp>>=8;
    data[7]=uint8_t(ultmp);

    data[8]=0; data[9]=0;

    myDCIF->setUserWriteData(WRcmd, 0, 8, data);
    myDCIF->setUserReadData(RDcmd);
    myDCIF->sendUserData(selectedSlaveAddr);
    cycl_running=1;

}


bool T_datif::verifyLineTestresponse(uint8_t RdDlen, uint8_t *receivedData)
{
    if (RdDlen < 16)
        return false;
    QString myStr;
    char ctmp;

    myStr.clear();
    myStr.append("< Slave Response");

    for (int nn=0; nn<16; nn++)
    {
        ctmp=receivedData[nn];
        if (myStr[nn] != ctmp)
        {
            //qDebug() << " datif cmd 10: got wrong string ";
            //qDebug() << myStr;
            //qDebug() << receivedData;
            //qDebug() << nn;
            return false;
        }
    }
    return true;
}


// RTC ----------------------------------------------------------------------

void T_datif::datif_OUT_setTime(void)
{
    // send PC time/date to slave
    //uint8_t hour,min, sec, year, month, day, dayOfWeek,
    //uint8_t dayOfYear, isLeap, weekOfYear;
    uint8_t buff[15];
    uint16_t uitmp;

    QTime *systTime = new QTime();
    //    qDebug()  << systTime->currentTime().hour()   <<":"
    //              << systTime->currentTime().minute() <<":"
    //              << systTime->currentTime().second();

    buff[0]=uint8_t(systTime->currentTime().hour());
    buff[1]=uint8_t(systTime->currentTime().minute());
    buff[2]=uint8_t(systTime->currentTime().second());


    QDate *systDate = new QDate();
    systDate->currentDate();

    uitmp= uint16_t(systDate->currentDate().year());
    buff[3]=uint8_t(uitmp);
    buff[4]=uint8_t(uitmp>>8);

    buff[5]=uint8_t(systDate->currentDate().month());
    buff[6]=uint8_t(systDate->currentDate().day());
    buff[7]=uint8_t(systDate->currentDate().dayOfWeek());

//    uitmp=systDate->currentDate().dayOfYear();
//    buff[8]=uint8_t(uitmp);
//    buff[9]=uint8_t(uitmp>>8);

//    buff[10]=uint8_t(systDate->currentDate().isLeapYear(systDate->currentDate().year()));
//    buff[11]=uint8_t(systDate->currentDate().weekNumber());   //weekOfYear
//    buff[12]=0;

    //myDCIF->setUserWriteData(0x1310,0,8, buff);
    myDCIF->setUserWriteData(CMD2DC_sendTime,0,8, buff);
    myDCIF->setUserReadData(0);
    myDCIF->sendUserData(selectedSlaveAddr);       // jetzt wegsckicken
    cycl_running=1;

}

// 0x2311: set time to RTC
// 0x2312: set date to RTC

uint8_t T_datif::datif_OUT_SendRandomData(uint8_t *buf, uint8_t Length)
{
    uint8_t    len=Length;

    myDCIF->setBLsendData(len, buf );
    myDCIF->setUserReadData(0);
    myDCIF->sendUserData(selectedSlaveAddr);
    cycl_running=1;

    return 0;

}




void T_datif::datif_send64byteOutCmd(uint16_t WRcmd, uint16_t addr, uint16_t RDcmd)
{
    // sending length is already defined by stored data
    // not batched! don't use twice within 100ms
    uint8_t LL;
    uint8_t data[66];

    tslib_strclr(data,0,66);    // up to 64 used
    gpi_restore64ByteSendData(&LL, data);   // LL bytes was stored to be sent
    myDCIF->setUserWriteData(WRcmd, addr, LL, data);
    myDCIF->setUserReadData(RDcmd);
    myDCIF->sendUserData(selectedSlaveAddr);
    cycl_running=1;

}

void T_datif::datif_sendToMemory(uint16_t WRcmd, uint16_t docNr, uint16_t blockNr, uint8_t *data64)
{
    // send printer documents to DC2 memory
    // docNr: 0...15(31)    with 1280 byte each (20 blocks a 64byte)
    // blockNr=0...19   with 64byte each
    // docNr =transmitted in WRITEADDRESS high byte
    // blockNr=transmitted in WRITEADDRESS low byte

    uint16_t aa=0;

    aa=docNr;
    aa<<=8;
    aa |=blockNr;
    myDCIF->setUserWriteData(WRcmd, aa, 64, data64);
    myDCIF->setUserReadData(0);
    myDCIF->sendUserData(selectedSlaveAddr);
    cycl_running=1;

}



