Compare commits
	
		
			1 Commits
		
	
	
		
			kleipeda
			...
			bad-neuena
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1d8dfcfa22 | 
@@ -146,11 +146,8 @@ struct CALCULATE_LIBRARY_API CalcState {
 | 
			
		||||
            s = CalcState::ABOVE_MAX_PARKING_TIME;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (m_desc.size() > 0) {
 | 
			
		||||
        return s + ":" + m_desc;
 | 
			
		||||
    }
 | 
			
		||||
        return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    explicit operator QString () const noexcept {
 | 
			
		||||
        QString s;
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@ public:
 | 
			
		||||
    // helper function to find time steps for a tariff with PaymentMethod::Steps
 | 
			
		||||
    // (e.g. Schoenau/Koenigsee)
 | 
			
		||||
    //
 | 
			
		||||
    QList<int> &GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0) const;
 | 
			
		||||
    QList<int> GetTimeSteps(Configuration *cfg, int paymentOptionIndex=0) const;
 | 
			
		||||
    QList<int> GetSteps(Configuration *cfg, int paymentOptionIndex=0) const { return GetTimeSteps(cfg, paymentOptionIndex); }
 | 
			
		||||
 | 
			
		||||
    QList<int> GetPriceSteps(Configuration *cfg) const;
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ int CALCULATE_LIBRARY_API get_minimal_parkingtime(Configuration const *cfg,
 | 
			
		||||
 | 
			
		||||
    switch(permitType) {
 | 
			
		||||
    case PERMIT_TYPE::SHORT_TERM_PARKING: { // e.g. szeged (customer_281)
 | 
			
		||||
        QList<int> const tsteps = Calculator::GetInstance().GetTimeSteps((Configuration *)cfg, paymentOptionIndex);
 | 
			
		||||
        Q_UNUSED(tsteps);
 | 
			
		||||
        minTime = cfg->getPaymentOptions(paymentOptionIndex).pop_min_time;
 | 
			
		||||
    } break;
 | 
			
		||||
    case PERMIT_TYPE::DAY_TICKET_ADULT: {
 | 
			
		||||
@@ -372,31 +374,8 @@ int CALCULATE_LIBRARY_API compute_next_timestep(parking_tariff_t *tariff, int cu
 | 
			
		||||
        // progressive tariff: e.g. Neuhauser, Kirchdorf (743)
 | 
			
		||||
        (paymentMethodId == PaymentMethod::Progressive))
 | 
			
		||||
    {
 | 
			
		||||
        QList<int> &stepList = Calculator::GetInstance().GetTimeSteps(tariff);
 | 
			
		||||
        int const size = stepList.size();
 | 
			
		||||
        if (size == 0) {
 | 
			
		||||
            qCritical() << "compute_next_timestep() *ERROR empty step-list*";
 | 
			
		||||
            return  currentTimeMinutes;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qCritical() << "   compute_next_timestep()      first time step:" << stepList[0];
 | 
			
		||||
        const QList<int> stepList = Calculator::GetInstance().GetTimeSteps(tariff);
 | 
			
		||||
        qCritical() << "   compute_next_timestep()     timeSteps:" << stepList;
 | 
			
		||||
        qCritical() << "   compute_next_timestep() currentTimeInMinutes:" << currentTimeMinutes;
 | 
			
		||||
 | 
			
		||||
        // consider time shift: the step-list might have been computed at a
 | 
			
		||||
        // slightly different time point
 | 
			
		||||
        int maxStep = -1;
 | 
			
		||||
        if (size >= 2) {
 | 
			
		||||
            maxStep = stepList[1] - stepList[0];
 | 
			
		||||
        }
 | 
			
		||||
        int tolerance = (maxStep == -1) ? 5 : std::min(maxStep, 5);
 | 
			
		||||
        if (std::abs(stepList[0] - currentTimeMinutes) <= tolerance) {
 | 
			
		||||
            qCritical().noquote()
 | 
			
		||||
                << QString("   compute_next_timestep() correction stepList[0]=%1 -> %2:")
 | 
			
		||||
                                    .arg(stepList[0]).arg(currentTimeMinutes);
 | 
			
		||||
            stepList[0] = currentTimeMinutes;
 | 
			
		||||
            qCritical() << "   compute_next_timestep()        NEW timeSteps:" << stepList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int currentStepIndex = stepList.indexOf(currentTimeMinutes);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -170,7 +170,7 @@ std::string Calculator::GetDurationFromCost(Configuration* cfg,
 | 
			
		||||
                    // in this case, adapt inputDate accordingly.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_GET_DURATION_FROM_COST 1
 | 
			
		||||
// #define DEBUG_GET_DURATION_FROM_COST 1
 | 
			
		||||
#if DEBUG_GET_DURATION_FROM_COST==1
 | 
			
		||||
                    qCritical() << DBG_HEADER << "PRE-PAID-OPTION: ADAPT-INPUT-DATE" << inputDate.toString(Qt::ISODate);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2090,13 +2090,12 @@ QList<int> Calculator::GetPriceSteps(Configuration * /*cfg*/) const {
 | 
			
		||||
    return QList<int>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QList<int> &Calculator::GetTimeSteps(Configuration *cfg, int paymentOptionIndex) const {
 | 
			
		||||
    qCritical() << "(" << __func__ << ":" << __LINE__ << ")              paymentOptionIndex:" << paymentOptionIndex;
 | 
			
		||||
QList<int> Calculator::GetTimeSteps(Configuration *cfg, int paymentOptionIndex) const {
 | 
			
		||||
    qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << "paymentOptionIndex:" << paymentOptionIndex;
 | 
			
		||||
 | 
			
		||||
    if (m_timeSteps.size() > paymentOptionIndex) {
 | 
			
		||||
        if (!m_timeSteps[paymentOptionIndex].isEmpty()) {
 | 
			
		||||
        //qCritical() << __PRETTY_FUNCTION__ << "timeSteps:" << m_timeSteps;
 | 
			
		||||
        return m_timeSteps[paymentOptionIndex];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        m_timeSteps.push_back(QList<int>());
 | 
			
		||||
    }
 | 
			
		||||
@@ -2201,7 +2200,7 @@ QList<int> &Calculator::GetTimeSteps(Configuration *cfg, int paymentOptionIndex)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qCritical() << "(" << __func__ << ":" << __LINE__ << ")                   NEW timeSteps:" << m_timeSteps;
 | 
			
		||||
    qCritical() << "(" << __func__ << ":" << __LINE__ << ")" << "NEW timeSteps:" << m_timeSteps;
 | 
			
		||||
 | 
			
		||||
    return m_timeSteps[paymentOptionIndex];
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,882 +0,0 @@
 | 
			
		||||
#include "MessageHelper.h"
 | 
			
		||||
#include "terminal_utils.h"
 | 
			
		||||
#include "aes128.h"
 | 
			
		||||
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#define IUC_ASYNCHPOS_COINCOIDE_H               0x09
 | 
			
		||||
#define IUC_ASYNCHPOS_COINCOIDE_L               0x78
 | 
			
		||||
#define IUC_ASYNCHPOS_MAX_ARRAY_SIZE	        1024
 | 
			
		||||
#define IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE	    300
 | 
			
		||||
#define IUC_ASYNCHPOS_MAX_RX_PACKET_SIZE	    10000   // 17000
 | 
			
		||||
#define IUC_ASYNCHPOS_MIN_PACKET_SIZE	        16
 | 
			
		||||
#define IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE        32
 | 
			
		||||
#define IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE   16
 | 
			
		||||
#define IUC_ASYNCHPOS_POLYNOME	                0xedb88320	// 0x04C11DB7
 | 
			
		||||
#define IUC_ASYNCHPOS_POLYNOME_INITIAL	        0		    // 0xFFFFFFFF
 | 
			
		||||
#define IUC_ASYNCHPOS_PRINTTIMOUT               1000
 | 
			
		||||
 | 
			
		||||
#define PACKET_ID_SIZE      8
 | 
			
		||||
#define MAX_POSID_LENGTH    255
 | 
			
		||||
 | 
			
		||||
#define STX     ((char)0x01)
 | 
			
		||||
#define ETX1    ((char)0x02)
 | 
			
		||||
#define ETX2    ((char)0x03)
 | 
			
		||||
#define EOT     ((char)0x04)
 | 
			
		||||
#define ENQ     ((char)0x05)
 | 
			
		||||
#define ACK1    ((char)0x06)
 | 
			
		||||
#define ACK2    ((char)0x07)
 | 
			
		||||
#define DLE     ((char)0x10)
 | 
			
		||||
#define NAK     ((char)0x15)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define DBG_HEADER "(" << __func__ << ":" << __LINE__ << ")"
 | 
			
		||||
 | 
			
		||||
#define DBG_EMERGENCY   (0) // System is unusable
 | 
			
		||||
#define DBG_ALERT       (1) // Action must be taken immediately
 | 
			
		||||
#define DBG_CRITICAL    (2) // Critical conditions
 | 
			
		||||
#define DBG_ERROR       (3) // Error conditions
 | 
			
		||||
#define DBG_WARNING     (4) // Warning conditions
 | 
			
		||||
#define DBG_NOTICE      (5) // Normal but significant conditions
 | 
			
		||||
                            // Conditions that are not error conditions, but that may require special handling
 | 
			
		||||
#define DBG_INFORMATION (6) // Informational messages
 | 
			
		||||
                            // Confirmation that the program is working as expected
 | 
			
		||||
#define DBG_DEBUG       (7) // Debug-level messages
 | 
			
		||||
                            // Messages that contain information normally of use only when debugging a program
 | 
			
		||||
 | 
			
		||||
static int DBG_LEVEL = DBG_INFORMATION;
 | 
			
		||||
//static int DBG_LEVEL = DBG_DEBUG;
 | 
			
		||||
 | 
			
		||||
struct MessageHeader {
 | 
			
		||||
    uint8_t packetType;
 | 
			
		||||
    uint8_t packetID[PACKET_ID_SIZE];
 | 
			
		||||
    uint8_t POSIDLength;
 | 
			
		||||
    uint8_t POSID[MAX_POSID_LENGTH];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MessageHelper::AsynchBillData MessageHelper::m_asyncBillData;
 | 
			
		||||
MessageHelper::AuthorizationResult MessageHelper::m_authorizationResult;
 | 
			
		||||
 | 
			
		||||
MessageHelper::MessageHelper(QString const &posID, QString const &apak)
 | 
			
		||||
  : m_posID(posID.toUtf8().constData())
 | 
			
		||||
  , m_posIDLength(m_posID.size())
 | 
			
		||||
  , m_messageHeaderPrefix(1 + PACKET_ID_SIZE + 1, 0x00)
 | 
			
		||||
  , m_rawPacket(IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE, 0x00) {
 | 
			
		||||
    m_messageHeaderPrefix[9] = (uint8_t)m_posID.size();
 | 
			
		||||
 | 
			
		||||
    for (int p = 0; p < apak.size(); p+=2) {
 | 
			
		||||
        uint8_t n = strtoul(apak.mid(p, 2).toStdString().c_str(), nullptr, 16);
 | 
			
		||||
        m_apak.push_back(n);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << apak << m_apak.toHex(':');
 | 
			
		||||
        qCritical() << DBG_HEADER << m_posID.toHex(':');
 | 
			
		||||
        qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MessageHelper::MessageHelper(QByteArray const &posID, QString const &apak)
 | 
			
		||||
  : m_posID(posID)
 | 
			
		||||
  , m_posIDLength(m_posID.size())
 | 
			
		||||
  , m_messageHeaderPrefix(1 + PACKET_ID_SIZE + 1, 0x00)
 | 
			
		||||
  , m_rawPacket(IUC_ASYNCHPOS_MAX_TX_PACKET_SIZE, 0x00) {
 | 
			
		||||
    m_messageHeaderPrefix[9] = (uint8_t)m_posID.size();
 | 
			
		||||
 | 
			
		||||
    for (int p = 0; p < apak.size(); p+=2) {
 | 
			
		||||
        uint8_t n = strtoul(apak.mid(p, 2).toStdString().c_str(), nullptr, 16);
 | 
			
		||||
        m_apak.push_back(n);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << apak << m_apak.toHex(':');
 | 
			
		||||
        qCritical() << DBG_HEADER << m_posID.toHex(':');
 | 
			
		||||
        qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MessageHelper::~MessageHelper() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::handleMessage(char const *pData) {
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
    //unsigned char marker = pData[0];
 | 
			
		||||
//	unsigned int tagNameLength = pData[1];
 | 
			
		||||
    unsigned char tagName[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
 | 
			
		||||
//	unsigned int curElementLength = 0;
 | 
			
		||||
    //unsigned char curElement[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
 | 
			
		||||
    //unsigned char receiptData[IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1];
 | 
			
		||||
    unsigned char rxBuf[20];
 | 
			
		||||
//	unsigned char flags[129];
 | 
			
		||||
//	unsigned char docNr[32];
 | 
			
		||||
    //unsigned char messageType = pData[1];
 | 
			
		||||
 | 
			
		||||
    unsigned int uitmp = 0;
 | 
			
		||||
    unsigned int uitmp2 = 0;
 | 
			
		||||
 | 
			
		||||
    iuc_asynchpos_sub_initArray(tagName, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE);
 | 
			
		||||
    //iuc_asynchpos_sub_initArray(curElement, IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE);
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("LoginResult",pData) | biox_FindStrInBuffer("LOGINRESULT",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        asynchState = 0x02;	//eingeloggt
 | 
			
		||||
        /*rxBuf[0] = 0x45;
 | 
			
		||||
        rxBuf[1] = 0x00;
 | 
			
		||||
        rxBuf[2] = 0x00;
 | 
			
		||||
        vmc_SendWithBuffer(rxBuf,40,0x69,0);*/
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("AuthorizationStarted",pData) | biox_FindStrInBuffer("AUTHORIZATIONSTARTED",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        iuc_asynchpos_sub_initArray(rxBuf,5);
 | 
			
		||||
        rxBuf[0] = 0x53;
 | 
			
		||||
        rxBuf[1] = 0x00;
 | 
			
		||||
        rxBuf[2] = 0x00;
 | 
			
		||||
        vmc_SendWithBuffer(rxBuf,5,0x69,0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("AuthorizationResult",pData) | biox_FindStrInBuffer("AUTHORIZATIONRESULT",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        asynchState = 0x03; //successfully authorized
 | 
			
		||||
        iuc_asynchpos_sub_clear_message(0x00);
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("ID",pData);
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]);
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData);
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]);
 | 
			
		||||
        //uitmp = biox_FindStrInBuffer("Result",pData) | biox_FindStrInBuffer("RESULT",pData);
 | 
			
		||||
        //biox_CopyBlock(pData, uitmp + 2, asynchBill.result, 0, pData[uitmp + 1]);
 | 
			
		||||
 | 
			
		||||
        brd_SendDiagStr("->IUC ASYNCHPOS message ID: ",0);
 | 
			
		||||
        brd_SendDiagBlock(asynchBill.id,1,36);
 | 
			
		||||
 | 
			
		||||
        /*if (iuc_asynch_PrintControl) {
 | 
			
		||||
            brd_SendDiagStr("->IUC ASYNCHPOS print data send AUTH: ",1);
 | 
			
		||||
            vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0);
 | 
			
		||||
            iuc_asynch_PrintControl = 0x00;
 | 
			
		||||
            //biox_delay_ms(750);
 | 
			
		||||
        }   else {
 | 
			
		||||
            brd_SendDiagStr("->IUC ASYNCHPOS sending authorization: ",1);
 | 
			
		||||
            iuc_asynch_PrintControl = 0x01;
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("ERROR",pData);
 | 
			
		||||
        if (!uitmp/*biox_FindStrInBuffer("OK",pData) | biox_FindStrInBuffer("Approved",pData) | biox_FindStrInBuffer("APPROVED",asynchBill.result)*/) {
 | 
			
		||||
            iuc_asynch_PrintControl |= 0xF0;
 | 
			
		||||
            /*uitmp = biox_FindStrInBufferInt("Amount",pData) | biox_FindStrInBufferInt("AMOUNT",pData);
 | 
			
		||||
            //if (pData[uitmp + 1] <= 10) {
 | 
			
		||||
                biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, pData[uitmp + 1]);
 | 
			
		||||
            //} else {
 | 
			
		||||
                //biox_CopyBlock(pData, uitmp + 2, asynchBill.amount, 0, 10);
 | 
			
		||||
            //}*/
 | 
			
		||||
 | 
			
		||||
            //uitmp = biox_FindStrInBuffer("Token",pData);
 | 
			
		||||
            //biox_CopyBlock(pData, uitmp + 2, asynchBill.token, 0, pData[uitmp + 1]);
 | 
			
		||||
            /*uitmp = biox_FindStrInBufferInt("Authcode",pData) | biox_FindStrInBufferInt("AUTHCODE",pData);
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, asynchBill.authCode, 0, pData[uitmp + 1]);
 | 
			
		||||
            uitmp = biox_FindStrInBufferInt("RRN",pData);
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, asynchBill.rrn, 0, pData[uitmp + 1]);
 | 
			
		||||
            uitmp = biox_FindStrInBufferInt("STAN",pData);
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, asynchBill.stan, 0, pData[uitmp + 1]);
 | 
			
		||||
            uitmp = biox_FindStrInBufferInt("CardType",pData) | biox_FindStrInBufferInt("CARDTYPE",pData);
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, asynchBill.cardtype, 0, pData[uitmp + 1]);*/
 | 
			
		||||
            asynchState = 0x04;
 | 
			
		||||
 | 
			
		||||
            brd_SendDiagStr("->IUC ASYNCHPOS authorization confirmed.",1);
 | 
			
		||||
 | 
			
		||||
            /*iuc_asynchpos_sub_initArray(rxBuf,20);
 | 
			
		||||
            rxBuf[0] = 0x45;
 | 
			
		||||
            rxBuf[1] = 0x00;
 | 
			
		||||
            rxBuf[2] = 0x00;
 | 
			
		||||
            vmc_SendWithBuffer(rxBuf,20,0x69,0);*/
 | 
			
		||||
 | 
			
		||||
            //iuc_asynchpos_resetBuffers(0x01);
 | 
			
		||||
            //iuc_asynchpos_command_close_Document();
 | 
			
		||||
        } else {
 | 
			
		||||
            iuc_asynch_PrintControl |= 0xF0;
 | 
			
		||||
            //uitmp = biox_FindStrInBufferInt("ErrCode",pData) | biox_FindStrInBufferInt("ERRCODE",pData);
 | 
			
		||||
            //biox_CopyBlock(pData, uitmp + 2, asynchBill.errCode, 0, pData[uitmp + 1]);
 | 
			
		||||
 | 
			
		||||
            brd_SendDiagStr("->IUC ASYNCHPOS authorization failed.",1);
 | 
			
		||||
 | 
			
		||||
            /*iuc_asynchpos_sub_initArray(rxBuf,20);
 | 
			
		||||
            rxBuf[0] = 0x45;
 | 
			
		||||
            rxBuf[1] = 0xFF;
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, rxBuf, 2, pData[uitmp + 1]);
 | 
			
		||||
            vmc_SendWithBuffer(rxBuf,20,0x69,0);*/
 | 
			
		||||
            iuc_asynch_keepAlive = 0x00;
 | 
			
		||||
            //VendRequest=0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("PrintReceipt",pData) | biox_FindStrInBufferInt("PRINTRECEIPT",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        asynchState = 0x03; //Customer receipt recieved
 | 
			
		||||
        //iuc_asynchpos_sub_initArray(flags,129);
 | 
			
		||||
        //uitmp = biox_FindStrInBufferInt("Flag",pData) | biox_FindStrInBufferInt("FLAG",pData) | biox_FindStrInBufferInt("Flags",pData) | biox_FindStrInBufferInt("FLAGS",pData);
 | 
			
		||||
        /*if (uitmp) {
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, flags, 0, pData[uitmp + 1]);
 | 
			
		||||
            uitmp = biox_FindStrInBufferInt("CD",flags) | biox_FindStrInBufferInt("LR",flags);
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        /*iuc_asynchpos_sub_clear_message(0x00);
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("ID",pData);
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, asynchBill.id, 0, pData[uitmp + 1]);
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("DocNr",pData) | biox_FindStrInBuffer("DOCNR",pData);
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, asynchBill.docNr, 0, pData[uitmp + 1]);*/
 | 
			
		||||
        iuc_asynchpos_sub_initArray(asynchBill.printId,129);
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("ID",pData);
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, asynchBill.printId, 0, pData[uitmp + 1]);
 | 
			
		||||
 | 
			
		||||
        //if(asynchState == 0x02/* && uitmp biox_FindStrInBufferInt("CD",flags) || biox_FindStrInBufferInt("LR",flags)*/) {
 | 
			
		||||
        if((!iuc_asynch_PRNrecieved) && (biox_FindStrInBufferInt("CD",pData) || biox_FindStrInBufferInt("LR",pData)) )	{
 | 
			
		||||
            iuc_asynch_PRNrecieved = 0x01;
 | 
			
		||||
            iuc_asynchpos_sub_initArray(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE + 1);
 | 
			
		||||
            uitmp = /*biox_FindStrInBuffer("ReceiptText",pData) | */biox_FindStrInBufferInt("RECEIPTTEXT",pData);
 | 
			
		||||
            uitmp2 = (pData[uitmp] * 256) + pData[uitmp + 1];
 | 
			
		||||
 | 
			
		||||
            //if (uitmp2 <= IUC_ASYNCHPOS_MAX_ARRAY_SIZE) {
 | 
			
		||||
            if (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) {
 | 
			
		||||
                uitmp2 = IUC_ASYNCHPOS_MAX_ARRAY_SIZE;
 | 
			
		||||
                brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large! Cutting off.",1);
 | 
			
		||||
                /*receiptData[0] = 0x50;
 | 
			
		||||
                biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*);
 | 
			
		||||
                //uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE;
 | 
			
		||||
                //uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE;
 | 
			
		||||
 | 
			
		||||
                brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0);
 | 
			
		||||
                brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
 | 
			
		||||
                iuc_asynch_PrintControl |= 0x0F;*/
 | 
			
		||||
 | 
			
		||||
                /*if (iuc_asynch_PrintControl) {
 | 
			
		||||
                    brd_SendDiagStr("->IUC ASYNCHPOS print data send: ",1);
 | 
			
		||||
                    vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0);
 | 
			
		||||
                    iuc_asynch_PrintControl = 0x00;
 | 
			
		||||
                } else {
 | 
			
		||||
                    brd_SendDiagStr("->IUC ASYNCHPOS print data stored: ",1);
 | 
			
		||||
                    iuc_asynch_PrintControl = 0x01;
 | 
			
		||||
                }*/
 | 
			
		||||
                //biox_delay_ms(750);
 | 
			
		||||
 | 
			
		||||
                //iuc_asynchpos_resetBuffers(0x01);
 | 
			
		||||
                //iuc_asynchpos_command_close_Document();
 | 
			
		||||
 | 
			
		||||
                //iuc_asynchpos_resetBuffers(0x02);
 | 
			
		||||
                //iuc_asynchpos_command_print_Result(0x01);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            receiptData[0] = 0x50;
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, receiptData, 1, uitmp2/*IUC_ASYNCHPOS_MAX_ARRAY_SIZE*/);
 | 
			
		||||
 | 
			
		||||
            brd_SendDiagStr("->IUC ASYNCHPOS receipt: ",0);
 | 
			
		||||
            brd_SendDiagBlock(receiptData,1,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
 | 
			
		||||
            iuc_asynch_PrintControl |= 0x0F;
 | 
			
		||||
 | 
			
		||||
            /* else {
 | 
			
		||||
                //receiptData[0] = 0x50;
 | 
			
		||||
                //iuc_asynchpos_sub_initZero(receiptData,1);
 | 
			
		||||
                brd_SendDiagStr("->IUC ASYNCHPOS receipt: ERROR. Receipt too large!",1);
 | 
			
		||||
                iuc_asynch_PrintControl |= 0x0E;
 | 
			
		||||
            } */
 | 
			
		||||
            /* else {
 | 
			
		||||
                //iuc_asynchpos_resetBuffers(0x02);
 | 
			
		||||
                iuc_asynchpos_command_print_Result(0x00);
 | 
			
		||||
            }*/
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //++iuc_print_counter;
 | 
			
		||||
 | 
			
		||||
        //if(asynchState == 0x04 && iuc_asynch_PrintControl == 0) {
 | 
			
		||||
            //iuc_asynchpos_resetBuffers(0x01);
 | 
			
		||||
            //iuc_asynchpos_resetBuffers(0x00);
 | 
			
		||||
            //iuc_asynchpos_command_print_Result(0x01);
 | 
			
		||||
        /*} /else {
 | 
			
		||||
            //iuc_asynchpos_resetBuffers(0x02);
 | 
			
		||||
            iuc_asynchpos_command_print_Result(0x01);
 | 
			
		||||
        }*/
 | 
			
		||||
            //iuc_asynchpos_command_print_Result(0x01);
 | 
			
		||||
 | 
			
		||||
        /*while (uitmp2 > IUC_ASYNCHPOS_MAX_ARRAY_SIZE) {
 | 
			
		||||
            biox_CopyBlock(pData, uitmp + 2, receiptData, 0, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
 | 
			
		||||
            uitmp += IUC_ASYNCHPOS_MAX_ARRAY_SIZE;
 | 
			
		||||
            uitmp2 -= IUC_ASYNCHPOS_MAX_ARRAY_SIZE;
 | 
			
		||||
            vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Rest des Packets
 | 
			
		||||
        biox_CopyBlock(pData, uitmp + 2, receiptData, 0, uitmp2);
 | 
			
		||||
        vmc_SendWithBuffer(receiptData,uitmp2,0x69,0);
 | 
			
		||||
 | 
			
		||||
        //iuc_asynchpos_resetBuffers(0x02);
 | 
			
		||||
        iuc_asynchpos_command_print_Result(0x01);*/
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("VoidResult",pData) | biox_FindStrInBufferInt("VOIDRESULT",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        asynchState = 0x01; //There was a cancel. Relogin and try again.
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("ERROR",pData);
 | 
			
		||||
        if (uitmp) {
 | 
			
		||||
            rxBuf[0] = 0x45;
 | 
			
		||||
            rxBuf[1] = 0x56;
 | 
			
		||||
            rxBuf[2] = 0x45;
 | 
			
		||||
            vmc_SendWithBuffer(rxBuf,3,0x69,0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uitmp = biox_FindStrInBufferInt("REFUND",pData);
 | 
			
		||||
        if (uitmp) {
 | 
			
		||||
            rxBuf[0] = 0x45;
 | 
			
		||||
            rxBuf[1] = 0x56;
 | 
			
		||||
            rxBuf[2] = 0x52;
 | 
			
		||||
            vmc_SendWithBuffer(rxBuf,3,0x69,0);
 | 
			
		||||
            //TODO refund bill here. Should not trigger, but it might.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uitmp = biox_FindStrInBufferInt("DocClosed",pData);
 | 
			
		||||
    if (uitmp) {
 | 
			
		||||
        asynchState = 0x01; //Transaction successful
 | 
			
		||||
 | 
			
		||||
        //if (VendRequest)
 | 
			
		||||
            GWstate.VendRequest=0;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::handleCommand(AsyncPosCommand command, char status) {
 | 
			
		||||
    //r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
    UCHAR	tempBuf[3];
 | 
			
		||||
    UCHAR	rxBuf[8];
 | 
			
		||||
//	UINT	uitemp = 0;
 | 
			
		||||
UINT uitmp= 700;
 | 
			
		||||
 | 
			
		||||
    tempBuf[0] = 0x00;
 | 
			
		||||
    tempBuf[1] = 0x00;
 | 
			
		||||
    tempBuf[2] = 0x00;
 | 
			
		||||
 | 
			
		||||
    timeHoldISMAS = GWglobTime.SecOfDay;
 | 
			
		||||
 | 
			
		||||
    iuc_asynchpos_sub_initArray(rxBuf,8);
 | 
			
		||||
    //iuc_asynchpos_resetBuffers(0x00);
 | 
			
		||||
 | 
			
		||||
    switch (command) {
 | 
			
		||||
        case 0x72:	//registration
 | 
			
		||||
                    //iuc_asynchpos_init();
 | 
			
		||||
                    asynchState = 0x01;
 | 
			
		||||
                    iuc_asynchpos_command_Login();
 | 
			
		||||
                    GWstate.VendRequest=1;
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x61:	//authorisation
 | 
			
		||||
                    iuc_asynch_keepAlive = 0x01;
 | 
			
		||||
                    iuc_asynch_PrintControl = 0;
 | 
			
		||||
                    iuc_asynchpos_sub_clear_message(0x01);
 | 
			
		||||
                    //VendRequest=1;
 | 
			
		||||
                    iuc_asynchpos_resetBuffers(0x00);
 | 
			
		||||
                    ///#ifdef IUC_ASYCHNPOS_TESTMODE
 | 
			
		||||
                    //iuc_asynchpos_command_authorize(uitmp);
 | 
			
		||||
                    //#else
 | 
			
		||||
                    iuc_asynchpos_command_authorize(Vend.Amount);
 | 
			
		||||
                    //#endif
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x63:	//cancel
 | 
			
		||||
        case 0x73:	//storno
 | 
			
		||||
                    /*if (asynchState <= 0x02 != 0) {	//Authorization result recieved?
 | 
			
		||||
                        iuc_asynchpos_command_cancel_authorize();
 | 
			
		||||
                    } else {*/
 | 
			
		||||
                        iuc_asynchpos_command_close_Document(0x01);
 | 
			
		||||
                    //}
 | 
			
		||||
                    iuc_asynch_keepAlive = 0x00;
 | 
			
		||||
                    //VendRequest=0;
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x6B:	//kassenschnitt
 | 
			
		||||
                    iuc_asynchpos_command_Logout();
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x62:	//get last bill
 | 
			
		||||
                    //iuc_zvt_getLastBill(tempBuf);
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x01:	iuc_asynchpos_command_close_Document(0x00);
 | 
			
		||||
                    iuc_asynch_keepAlive = 0x00;
 | 
			
		||||
                    //VendRequest=0;
 | 
			
		||||
                    break;
 | 
			
		||||
        case 0x70:	iuc_asynchpos_command_ping_terminal();
 | 
			
		||||
                    break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createRawPacket(PacketType packetType,
 | 
			
		||||
                                    QByteArray const &encryptedPacketID,
 | 
			
		||||
                                    QByteArray const &message) {
 | 
			
		||||
    if (createMessageHeaderPrefix(packetType, encryptedPacketID)) {
 | 
			
		||||
        QByteArray ba(m_messageHeaderPrefix);
 | 
			
		||||
        ba = ba.append(m_posID);
 | 
			
		||||
        ba = ba.append(message);
 | 
			
		||||
 | 
			
		||||
        uint16_t const size = ba.size();
 | 
			
		||||
 | 
			
		||||
        ba.push_front((char)size);
 | 
			
		||||
        ba.push_front((char)(size >> 8));
 | 
			
		||||
 | 
			
		||||
        m_rawPacket = ba;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MessageHelper::setMessageHeaderPacketType(PacketType packetType) {
 | 
			
		||||
 | 
			
		||||
    switch (packetType) {
 | 
			
		||||
    case PacketType::POS_ECR:
 | 
			
		||||
    case PacketType::MESSAGE_RECEIVED_POSITIVE_ACK:
 | 
			
		||||
    case PacketType::MESSAGE_RECEIVED_NEGATIVE_ACK:
 | 
			
		||||
        m_messageHeaderPrefix[0] = (uint8_t)packetType;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MessageHelper::createMessageHeaderPrefix(PacketType packetType, QByteArray const &encryptedPacketID) {
 | 
			
		||||
    if (encryptedPacketID.size() == PACKET_ID_SIZE) {
 | 
			
		||||
        if (setMessageHeaderPacketType(packetType)) {
 | 
			
		||||
            for (int i = 1; i <= 8; ++i) {
 | 
			
		||||
                m_messageHeaderPrefix[i] = (uint8_t)encryptedPacketID[i-1];
 | 
			
		||||
            }
 | 
			
		||||
            if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
                qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
QByteArray const &MessageHelper::generateUniqueTransactionID(QString const &machineNr,
 | 
			
		||||
                                                             QString const &customerNr) {
 | 
			
		||||
 | 
			
		||||
    // TODO: wieder entfernen
 | 
			
		||||
    QDateTime dt(QDateTime::fromString("2024-06-18T12:00:00", Qt::ISODate));
 | 
			
		||||
 | 
			
		||||
    uint64_t const transID = MessageHelper::secsSinceJan2017(dt);
 | 
			
		||||
 | 
			
		||||
    m_uniqueTransactionID.clear();
 | 
			
		||||
    m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(std::to_string(transID).c_str(), 9).rightJustified(10, '0'));
 | 
			
		||||
    m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(machineNr.toStdString().c_str()).rightJustified(5, '0'));
 | 
			
		||||
    m_uniqueTransactionID = m_uniqueTransactionID.append(QByteArray(customerNr.toStdString().c_str()).rightJustified(4, '0'));
 | 
			
		||||
 | 
			
		||||
    return m_uniqueTransactionID;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// actual payment. amount to pay is known.
 | 
			
		||||
void MessageHelper::createAuthorizeMessage() {
 | 
			
		||||
    m_authorizeMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x89); // 9 in 0x89 is the size
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Authorize"));
 | 
			
		||||
 | 
			
		||||
    QString const &price= m_price.setNum(1000);
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x06);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Amount"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)price.size());
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray(price.toStdString().c_str()));
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x04);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Cash"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x01);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x30);
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x08);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Currency"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x03);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("978"));
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x05);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("DocNr"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x13);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(generateUniqueTransactionID("1000", "100"));
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x04);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Time"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x13);
 | 
			
		||||
 | 
			
		||||
    QDateTime current = QDateTime::currentDateTime();
 | 
			
		||||
    // TODO: wieder entfernen
 | 
			
		||||
    current.setTime(QTime(12, 0, 0));
 | 
			
		||||
    current.setDate(QDate(2024, 6, 18));
 | 
			
		||||
 | 
			
		||||
    QByteArray time(current.toString(Qt::ISODate).toStdString().c_str());
 | 
			
		||||
    time[10] = ' ';
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray(time));
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x04);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("Lang"));
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x02);
 | 
			
		||||
    m_authorizeMessage = m_authorizeMessage.append(QByteArray("lt"));
 | 
			
		||||
 | 
			
		||||
    m_authorizeMessage.push_back((char)0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createCancelAuthorizeMessage() {
 | 
			
		||||
    m_cancelAuthorizeMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_cancelAuthorizeMessage.push_back((char)0x96); // 0x80 + 0x16
 | 
			
		||||
    m_cancelAuthorizeMessage = m_cancelAuthorizeMessage.append(QByteArray("AuthorizationCancelled"));
 | 
			
		||||
 | 
			
		||||
    m_cancelAuthorizeMessage.push_back((char)0x02);
 | 
			
		||||
    m_cancelAuthorizeMessage = m_authorizeMessage.append(QByteArray("ID"));
 | 
			
		||||
 | 
			
		||||
    m_cancelAuthorizeMessage.push_back((char)0x00);
 | 
			
		||||
    m_cancelAuthorizeMessage.push_back((char)QByteArray(m_asyncBillData.id).size());
 | 
			
		||||
    m_cancelAuthorizeMessage = m_cancelAuthorizeMessage.append(QByteArray(m_asyncBillData.id));
 | 
			
		||||
 | 
			
		||||
    m_cancelAuthorizeMessage.push_back((char)0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createPingMessage() {
 | 
			
		||||
    m_pingMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_pingMessage.push_back((char)0x84); // 4 in 0x84 is the size
 | 
			
		||||
    m_pingMessage = m_pingMessage.append(QByteArray("Ping"));
 | 
			
		||||
 | 
			
		||||
    m_pingMessage.push_back((char)0x04);
 | 
			
		||||
    m_pingMessage = m_authorizeMessage.append(QByteArray("Time"));
 | 
			
		||||
    m_pingMessage.push_back((char)0x00);
 | 
			
		||||
    m_pingMessage.push_back((char)0x13);
 | 
			
		||||
 | 
			
		||||
    QDateTime current = QDateTime::currentDateTime();
 | 
			
		||||
    // TODO: wieder entfernen
 | 
			
		||||
    current.setTime(QTime(12, 0, 0));
 | 
			
		||||
    current.setDate(QDate(2024, 6, 18));
 | 
			
		||||
 | 
			
		||||
    QByteArray time(current.toString(Qt::ISODate).toStdString().c_str());
 | 
			
		||||
    time[10] = ' ';
 | 
			
		||||
    m_pingMessage = m_pingMessage.append(QByteArray(time));
 | 
			
		||||
 | 
			
		||||
    m_pingMessage.push_back((char)0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createCloseDocumentMessage(bool storno) {
 | 
			
		||||
    m_closeDocumentMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_closeDocumentMessage.push_back((char)0x89); // 9 in 0x89 is the size
 | 
			
		||||
    m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("DocClosed"));
 | 
			
		||||
 | 
			
		||||
    m_closeDocumentMessage.push_back((char)0x05);
 | 
			
		||||
    m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("DocNr"));
 | 
			
		||||
 | 
			
		||||
    uint16_t const docNrSize = m_uniqueTransactionID.size();
 | 
			
		||||
 | 
			
		||||
    m_closeDocumentMessage.push_back((char)(docNrSize >> 8));
 | 
			
		||||
    m_closeDocumentMessage.push_back((char)(docNrSize));
 | 
			
		||||
    m_closeDocumentMessage = m_closeDocumentMessage.append(m_uniqueTransactionID);
 | 
			
		||||
 | 
			
		||||
    if (!storno) {
 | 
			
		||||
        m_closeDocumentMessage.push_back((char)0x06);
 | 
			
		||||
        m_closeDocumentMessage = m_closeDocumentMessage.append(QByteArray("AuthID"));
 | 
			
		||||
 | 
			
		||||
        QByteArray ba(m_authorizationResult.m_id.toStdString().c_str());
 | 
			
		||||
        uint16_t const authIdSize = ba.size();
 | 
			
		||||
 | 
			
		||||
        m_closeDocumentMessage.push_back((char)(authIdSize >> 8));
 | 
			
		||||
        m_closeDocumentMessage.push_back((char)(authIdSize));
 | 
			
		||||
 | 
			
		||||
        m_closeDocumentMessage = m_closeDocumentMessage.append(ba);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_closeDocumentMessage.push_back((char)0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createPrintResultMessage() {
 | 
			
		||||
    m_printResultMessage.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t MessageHelper::secsSinceJan2017(QDateTime const &dt) {
 | 
			
		||||
    return QDateTime(QDateTime::fromString("2017-01-01T00:00:00", Qt::ISODate)).secsTo(dt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createLoginMessage() {
 | 
			
		||||
    m_loginMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x85); // 5 in 0x85 is the size
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(QByteArray("Login"));
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x04);
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(QByteArray("Time"));
 | 
			
		||||
    m_loginMessage.push_back((char)0x00);
 | 
			
		||||
    m_loginMessage.push_back((char)0x13);
 | 
			
		||||
 | 
			
		||||
    QDateTime current = QDateTime::currentDateTime();
 | 
			
		||||
    // TODO: wieder entfernen
 | 
			
		||||
    current.setTime(QTime(12, 0, 0));
 | 
			
		||||
    current.setDate(QDate(2024, 6, 18));
 | 
			
		||||
 | 
			
		||||
    QByteArray time(current.toString(Qt::ISODate).toStdString().c_str());
 | 
			
		||||
    time[10] = ' ';
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(time);
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x05);
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(QByteArray("Flags"));
 | 
			
		||||
    m_loginMessage.push_back((char)0x00);
 | 
			
		||||
    m_loginMessage.push_back((char)0x06);
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(QByteArray("AP3|LR"));
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x00);
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_INFORMATION) {
 | 
			
		||||
        qCritical() << DBG_HEADER << "loginMessage" << m_loginMessage.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MessageHelper::createLogoutMessage() {
 | 
			
		||||
    m_logoutMessage.clear();
 | 
			
		||||
 | 
			
		||||
    m_logoutMessage.push_back((char)0x86); // 6 in 0x86 is the size
 | 
			
		||||
    m_logoutMessage = m_loginMessage.append(QByteArray("Logout"));
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x04);
 | 
			
		||||
    m_loginMessage = m_loginMessage.append(QByteArray("Time"));
 | 
			
		||||
    m_loginMessage.push_back((char)0x00);
 | 
			
		||||
    m_loginMessage.push_back((char)0x13);
 | 
			
		||||
 | 
			
		||||
    QDateTime current = QDateTime::currentDateTime();
 | 
			
		||||
    // TODO: wieder entfernen
 | 
			
		||||
    current.setTime(QTime(12, 0, 0));
 | 
			
		||||
    current.setDate(QDate(2024, 6, 18));
 | 
			
		||||
 | 
			
		||||
    QByteArray time(current.toString(Qt::ISODate).toStdString().c_str());
 | 
			
		||||
    time[10] = ' ';
 | 
			
		||||
    m_logoutMessage = m_logoutMessage.append(time);
 | 
			
		||||
 | 
			
		||||
    m_loginMessage.push_back((char)0x00);
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_INFORMATION) {
 | 
			
		||||
        qCritical() << DBG_HEADER << "loginMessage" << m_logoutMessage.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArrayList const &MessageHelper::createMessageChunksToSend(AsyncPosCommand cmd, char etx) {
 | 
			
		||||
    QByteArray encryptedPacketID(QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08"));
 | 
			
		||||
 | 
			
		||||
    m_messageChunkList.clear();
 | 
			
		||||
 | 
			
		||||
    switch (cmd) {
 | 
			
		||||
    case (int)MessageHelper::AsyncPosCommand::LOGIN:
 | 
			
		||||
        createLoginMessage();
 | 
			
		||||
        createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_loginMessage);
 | 
			
		||||
        break;
 | 
			
		||||
    case (int)MessageHelper::AsyncPosCommand::LOGOUT:
 | 
			
		||||
        createLogoutMessage();
 | 
			
		||||
        createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_logoutMessage);
 | 
			
		||||
        break;
 | 
			
		||||
    case (int)MessageHelper::AsyncPosCommand::AUTHORIZE:
 | 
			
		||||
        createAuthorizeMessage();
 | 
			
		||||
        createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_authorizeMessage);
 | 
			
		||||
        break;
 | 
			
		||||
    case (int)MessageHelper::AsyncPosCommand::CLOSE_DOCUMENT:
 | 
			
		||||
        createCloseDocumentMessage(); // actung: hier default parameter
 | 
			
		||||
        createRawPacket(PacketType::POS_ECR, encryptedPacketID, m_closeDocumentMessage);
 | 
			
		||||
        break;
 | 
			
		||||
    default:;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << m_rawPacket.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QByteArray const &ba = m_rawPacket.mid(11);
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << ba.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // calculate crc32 on message starting from (including) POSID length
 | 
			
		||||
    uint32_t crc = TU::crc32(ba);
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << "crc32" << hex << crc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned char cipherText[256];
 | 
			
		||||
    memset(cipherText, 0, sizeof(cipherText));
 | 
			
		||||
 | 
			
		||||
    // XOR crc32-value (4 bytes) with APAK starting from left
 | 
			
		||||
    // (rest of APAK untouched)
 | 
			
		||||
    QByteArray clearText(m_apak);
 | 
			
		||||
    clearText[0] = clearText[0] ^ ((uint8_t)(crc >> 24));
 | 
			
		||||
    clearText[1] = clearText[1] ^ ((uint8_t)(crc >> 16));
 | 
			
		||||
    clearText[2] = clearText[2] ^ ((uint8_t)(crc >>  8));
 | 
			
		||||
    clearText[3] = clearText[3] ^ ((uint8_t)(crc >>  0));
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
        qCritical() << DBG_HEADER << "clearText" << clearText.toHex();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // encrypt XOR result with APAK using AES129, ECB mode
 | 
			
		||||
    aes_encrypt((uint8_t *)clearText.data(),
 | 
			
		||||
                (uint8_t *)cipherText,
 | 
			
		||||
                (uint8_t *)m_apak.toStdString().c_str());
 | 
			
		||||
 | 
			
		||||
    // 8 left bytes of encryption result is signature (Packet ID)
 | 
			
		||||
    encryptedPacketID = QByteArray((const char *)cipherText, 8);
 | 
			
		||||
 | 
			
		||||
    if (DBG_LEVEL >= DBG_INFORMATION) {
 | 
			
		||||
        qCritical() << DBG_HEADER << "cipherText (new PacketID)" << encryptedPacketID.toHex(':');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // insert PacketID in packet
 | 
			
		||||
    if (insertEncryptedPacketID(encryptedPacketID)) {
 | 
			
		||||
 | 
			
		||||
        // build chunks to be sent over serial line
 | 
			
		||||
 | 
			
		||||
        int const chunks = m_rawPacket.size() / IUC_ASYNCHPOS_MIN_PACKET_SIZE;
 | 
			
		||||
 | 
			
		||||
        if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
            qCritical() << DBG_HEADER << "nr of chunks" << chunks;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        for (; i < chunks; ++i) {
 | 
			
		||||
            QByteArray messageChunk = m_rawPacket.mid(IUC_ASYNCHPOS_MIN_PACKET_SIZE*i,
 | 
			
		||||
                                                      IUC_ASYNCHPOS_MIN_PACKET_SIZE);
 | 
			
		||||
            if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
                qCritical() << DBG_HEADER << i << "unmasked" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            messageChunk = MessageHelper::mask(messageChunk);
 | 
			
		||||
 | 
			
		||||
            if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
                qCritical() << DBG_HEADER << i << "  masked" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            messageChunk.push_back(etx == ACK1 ? ETX2 : ETX1); // etx must be ACK1 or ACK2
 | 
			
		||||
 | 
			
		||||
            char const lrc = TU::lrc(messageChunk);
 | 
			
		||||
            messageChunk.push_back(lrc);
 | 
			
		||||
            messageChunk.push_front(STX);
 | 
			
		||||
 | 
			
		||||
            if (DBG_LEVEL >= DBG_INFORMATION) {
 | 
			
		||||
                qCritical() << DBG_HEADER << "chunk to send" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_messageChunkList += messageChunk;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int const rest = m_rawPacket.size() % IUC_ASYNCHPOS_MIN_PACKET_SIZE;
 | 
			
		||||
        if (rest) {
 | 
			
		||||
            QByteArray messageChunk = m_rawPacket.mid(IUC_ASYNCHPOS_MIN_PACKET_SIZE*chunks, rest);
 | 
			
		||||
 | 
			
		||||
            if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
                qCritical() << DBG_HEADER << i << "unmasked" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            messageChunk = mask(messageChunk);
 | 
			
		||||
 | 
			
		||||
            if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
                qCritical() << DBG_HEADER << i << "  masked" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            messageChunk.push_back(etx == ACK1 ? ETX2 : ETX1); // etx must be ACK1 or ACK2
 | 
			
		||||
 | 
			
		||||
            char const lrc = TU::lrc(messageChunk);
 | 
			
		||||
            messageChunk.push_back(lrc);
 | 
			
		||||
            messageChunk.push_front(STX);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (DBG_LEVEL >= DBG_INFORMATION) {
 | 
			
		||||
                qCritical() << DBG_HEADER << "chunk to send" << messageChunk.toHex(':');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_messageChunkList += messageChunk;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return m_messageChunkList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArrayList MessageHelper::createLoginMessageChunksToSend(char etx) {
 | 
			
		||||
    return createMessageChunksToSend(AsyncPosCommand::LOGIN, etx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArrayList MessageHelper::createLogoutMessageChunksToSend(char etx) {
 | 
			
		||||
    return createMessageChunksToSend(AsyncPosCommand::LOGOUT, etx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArrayList MessageHelper::createAuthorizeMessageChunksToSend(char etx) {
 | 
			
		||||
    return createMessageChunksToSend(AsyncPosCommand::AUTHORIZE, etx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArrayList MessageHelper::createCloseDocumentMessageChunksToSend(char etx) {
 | 
			
		||||
    return createMessageChunksToSend(AsyncPosCommand::CLOSE_DOCUMENT, etx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MessageHelper::insertEncryptedPacketID(QByteArray const &encryptedPacketID) {
 | 
			
		||||
    if (encryptedPacketID.size() == PACKET_ID_SIZE) {
 | 
			
		||||
        // m_rawPacket has already full length
 | 
			
		||||
        for (int i = 0; i < PACKET_ID_SIZE; ++i) {
 | 
			
		||||
            m_messageHeaderPrefix[i+1] = encryptedPacketID[i];
 | 
			
		||||
            m_rawPacket[i+3] = encryptedPacketID[i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (DBG_LEVEL >= DBG_DEBUG) {
 | 
			
		||||
            qCritical() << DBG_HEADER << m_messageHeaderPrefix.toHex(':');
 | 
			
		||||
            qCritical() << DBG_HEADER << m_rawPacket.toHex(':');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray const &MessageHelper::mask(QByteArray &messageChunk) {
 | 
			
		||||
    QByteArray ba;
 | 
			
		||||
    for (int i = 0; i < messageChunk.size(); ++i) {
 | 
			
		||||
        char const c = messageChunk[i];
 | 
			
		||||
        switch(c) {
 | 
			
		||||
        case STX:   __attribute__((fallthrough));
 | 
			
		||||
        case ETX1:  __attribute__((fallthrough));
 | 
			
		||||
        case ETX2:  __attribute__((fallthrough));
 | 
			
		||||
        case EOT:   __attribute__((fallthrough));
 | 
			
		||||
        case ENQ:   __attribute__((fallthrough));
 | 
			
		||||
        case ACK1:  __attribute__((fallthrough));
 | 
			
		||||
        case ACK2:  __attribute__((fallthrough));
 | 
			
		||||
        case DLE:   __attribute__((fallthrough));
 | 
			
		||||
        case NAK:
 | 
			
		||||
            ba.push_back(char(DLE));
 | 
			
		||||
            ba.push_back(c + 0x30);
 | 
			
		||||
        break;
 | 
			
		||||
        default:
 | 
			
		||||
            ba.push_back(c);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    messageChunk = ba;
 | 
			
		||||
    return messageChunk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray const &MessageHelper::unMask(QByteArray &messageChunk) {
 | 
			
		||||
    QByteArray ba;
 | 
			
		||||
    for (int i = 0; i < messageChunk.size(); ++i) {
 | 
			
		||||
        char c = messageChunk[i];
 | 
			
		||||
        if (c == (char)0x10) /* DEL */ {
 | 
			
		||||
            if ((i+1) < messageChunk.size()) {
 | 
			
		||||
                c = messageChunk[i+1] - (char)0x30;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ba.push_back(c);
 | 
			
		||||
    }
 | 
			
		||||
    messageChunk = ba;
 | 
			
		||||
    return messageChunk;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,112 +0,0 @@
 | 
			
		||||
#ifndef MESSAGE_HELPER_H_INCLUDED
 | 
			
		||||
#define MESSAGE_HELPER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <cinttypes>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QByteArrayList>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
 | 
			
		||||
class MessageHelper {
 | 
			
		||||
public:
 | 
			
		||||
    enum PacketType : std::uint8_t {
 | 
			
		||||
        POS_ECR = 0,
 | 
			
		||||
        // POS_EXT = 1,
 | 
			
		||||
        MESSAGE_RECEIVED_POSITIVE_ACK = 0x0A,
 | 
			
		||||
        MESSAGE_RECEIVED_NEGATIVE_ACK = 0x0F
 | 
			
		||||
        // POS_HOST_FORMAT_1_ENCRYPTED   = 0x11,
 | 
			
		||||
        // POS_HOST_FORMAT_1_UNENCRYPTED = 0x21
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum AsyncPosCommand : std::uint8_t {
 | 
			
		||||
        LOGIN  = 0,
 | 
			
		||||
        LOGOUT = 1,
 | 
			
		||||
        AUTHORIZE = 2,
 | 
			
		||||
        CLOSE_DOCUMENT = 3
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    explicit MessageHelper(QString const &posID = "T-TPS-SELF2002in",
 | 
			
		||||
                           QString const &apak = "8AC304380E0E476BA2558B75DB9E2516");
 | 
			
		||||
    explicit MessageHelper(QByteArray const &posID, QString const &apak);
 | 
			
		||||
    ~MessageHelper();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void createRawPacket(PacketType PacketType,
 | 
			
		||||
                         QByteArray const &encryptedPacketId,
 | 
			
		||||
                         QByteArray const &message);
 | 
			
		||||
 | 
			
		||||
    bool insertEncryptedPacketID(QByteArray const &encryptedPacketID);
 | 
			
		||||
 | 
			
		||||
    QByteArrayList createLoginMessageChunksToSend(char etx);
 | 
			
		||||
    QByteArrayList createLogoutMessageChunksToSend(char etx);
 | 
			
		||||
    QByteArrayList createAuthorizeMessageChunksToSend(char etx);
 | 
			
		||||
    QByteArrayList createCloseDocumentMessageChunksToSend(char etx);
 | 
			
		||||
    QByteArrayList const &createMessageChunksToSend(AsyncPosCommand cmd, char etx);
 | 
			
		||||
 | 
			
		||||
// private:
 | 
			
		||||
 | 
			
		||||
    QByteArray m_posID;
 | 
			
		||||
    QByteArray m_apak;
 | 
			
		||||
    uint8_t m_posIDLength;
 | 
			
		||||
    QByteArray m_messageHeaderPrefix;
 | 
			
		||||
    QByteArray m_rawPacket; // without leading STX and trailing [ETX(1/2), LRC]
 | 
			
		||||
    QByteArray m_loginMessage;
 | 
			
		||||
    QByteArray m_logoutMessage;
 | 
			
		||||
    QByteArray m_authorizeMessage;
 | 
			
		||||
    QByteArray m_cancelAuthorizeMessage;
 | 
			
		||||
    QByteArray m_pingMessage;
 | 
			
		||||
    QByteArray m_printResultMessage;
 | 
			
		||||
    QByteArray m_closeDocumentMessage;
 | 
			
		||||
    QByteArray m_uniqueTransactionID;
 | 
			
		||||
    QString m_price;
 | 
			
		||||
    QByteArrayList m_messageChunkList;
 | 
			
		||||
 | 
			
		||||
    bool setMessageHeaderPacketType(PacketType packetType);
 | 
			
		||||
 | 
			
		||||
    bool createMessageHeaderPrefix(PacketType packetType, QByteArray const &encryptedPacketID);
 | 
			
		||||
    void createLoginMessage();
 | 
			
		||||
    void createLogoutMessage();
 | 
			
		||||
    void createAuthorizeMessage();
 | 
			
		||||
    void createCancelAuthorizeMessage();
 | 
			
		||||
    void createPingMessage();
 | 
			
		||||
    void createCloseDocumentMessage(bool storno = false);
 | 
			
		||||
    void createPrintResultMessage();
 | 
			
		||||
 | 
			
		||||
    void handleCommand(AsyncPosCommand command, char status);
 | 
			
		||||
    //r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt
 | 
			
		||||
 | 
			
		||||
    void handleMessage(char const *pData);
 | 
			
		||||
 | 
			
		||||
    QByteArray const &generateUniqueTransactionID(QString const &machineNr, QString const &customerNumer);
 | 
			
		||||
 | 
			
		||||
    static QByteArray const &mask(QByteArray &messageChunk);
 | 
			
		||||
    static QByteArray const &unMask(QByteArray &messageChunk);
 | 
			
		||||
    static uint32_t secsSinceJan2017(QDateTime const &dt = QDateTime::currentDateTime());
 | 
			
		||||
 | 
			
		||||
    struct AsynchBillData {
 | 
			
		||||
        char time[20];
 | 
			
		||||
        char id[37];
 | 
			
		||||
        char printId[129];
 | 
			
		||||
        char docNr[33];
 | 
			
		||||
        //unsigned char amount[10];
 | 
			
		||||
        //unsigned char token[25];
 | 
			
		||||
        //unsigned char result[8];
 | 
			
		||||
        //unsigned char authCode[7];
 | 
			
		||||
        //unsigned char rrn[13];
 | 
			
		||||
        //unsigned char stan[7];
 | 
			
		||||
        //unsigned char cardtype[33];
 | 
			
		||||
        char errCode[17];
 | 
			
		||||
        //unsigned char receiptData[IUC_ASYNCHPOS_RECEIPT_LENGTH];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct AuthorizationResult {
 | 
			
		||||
        QString m_id;       // max. 36
 | 
			
		||||
        QString m_docNr;    // max. 32
 | 
			
		||||
        QString m_result;   // "OK" or "ERROR"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static AsynchBillData m_asyncBillData;
 | 
			
		||||
    static AuthorizationResult m_authorizationResult;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // MESSAGE_HELPER_H_INCLUDED
 | 
			
		||||
							
								
								
									
										625
									
								
								main/aes128.cpp
									
									
									
									
									
								
							
							
						
						
									
										625
									
								
								main/aes128.cpp
									
									
									
									
									
								
							@@ -1,625 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * aes128.c
 | 
			
		||||
 *
 | 
			
		||||
 * Created: 27.11.2017 13:33:29
 | 
			
		||||
 *  Author: Matthias
 | 
			
		||||
 */ 
 | 
			
		||||
 | 
			
		||||
#include <aes128.h>
 | 
			
		||||
 | 
			
		||||
/* the expanded keySize */
 | 
			
		||||
#define EXPANDED_KEY_SIZE 176
 | 
			
		||||
//int expandedKeySize;
 | 
			
		||||
 | 
			
		||||
/* the expanded key */
 | 
			
		||||
//unsigned char expandedKey[EXPANDED_KEY_SIZE];
 | 
			
		||||
 | 
			
		||||
/* the cipher key */
 | 
			
		||||
//unsigned char key[16];
 | 
			
		||||
 | 
			
		||||
/* the cipher key size */
 | 
			
		||||
 | 
			
		||||
enum keySize{
 | 
			
		||||
	SIZE_16 = 16,
 | 
			
		||||
	SIZE_24 = 24,
 | 
			
		||||
	SIZE_32 = 32
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//enum keySize size;
 | 
			
		||||
 | 
			
		||||
unsigned char sbox[256] =   {
 | 
			
		||||
	//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
 | 
			
		||||
	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
 | 
			
		||||
	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
 | 
			
		||||
	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
 | 
			
		||||
	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
 | 
			
		||||
	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
 | 
			
		||||
	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
 | 
			
		||||
	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
 | 
			
		||||
	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
 | 
			
		||||
	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
 | 
			
		||||
	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
 | 
			
		||||
	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
 | 
			
		||||
	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
 | 
			
		||||
	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
 | 
			
		||||
	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
 | 
			
		||||
	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
 | 
			
		||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
 | 
			
		||||
 | 
			
		||||
unsigned char rsbox[256] =
 | 
			
		||||
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
 | 
			
		||||
	, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
 | 
			
		||||
	, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
 | 
			
		||||
	, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
 | 
			
		||||
	, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
 | 
			
		||||
	, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
 | 
			
		||||
	, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
 | 
			
		||||
	, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
 | 
			
		||||
	, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
 | 
			
		||||
	, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
 | 
			
		||||
	, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
 | 
			
		||||
	, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
 | 
			
		||||
	, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
 | 
			
		||||
	, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
 | 
			
		||||
	, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
 | 
			
		||||
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
 | 
			
		||||
 | 
			
		||||
unsigned char Rcon[256] = {
 | 
			
		||||
 | 
			
		||||
	0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
 | 
			
		||||
	0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
 | 
			
		||||
	0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
 | 
			
		||||
	0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
 | 
			
		||||
	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
 | 
			
		||||
	0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
 | 
			
		||||
	0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
 | 
			
		||||
	0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
 | 
			
		||||
	0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
 | 
			
		||||
	0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
 | 
			
		||||
	0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
 | 
			
		||||
	0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
 | 
			
		||||
	0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
 | 
			
		||||
	0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
 | 
			
		||||
	0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
 | 
			
		||||
	0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
 | 
			
		||||
	0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
 | 
			
		||||
	0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
 | 
			
		||||
	0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
 | 
			
		||||
0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};
 | 
			
		||||
 | 
			
		||||
void aes_init() {
 | 
			
		||||
	//UINT uitemp = 0;
 | 
			
		||||
	/* the expanded keySize */
 | 
			
		||||
	//expandedKeySize = EXPANDED_KEY_SIZE;
 | 
			
		||||
 | 
			
		||||
	/* the cipher key */
 | 
			
		||||
	//for (uitemp = 0; uitemp < 16; ++uitemp)
 | 
			
		||||
		//key[uitemp] = 0x00;
 | 
			
		||||
 | 
			
		||||
	/* the cipher key size */
 | 
			
		||||
	//size = SIZE_16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned char getSBoxValue(unsigned char num)
 | 
			
		||||
{
 | 
			
		||||
	return sbox[num];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned char getSBoxInvert(unsigned char num)
 | 
			
		||||
{
 | 
			
		||||
	return rsbox[num];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Key generation
 | 
			
		||||
 | 
			
		||||
/* Rijndael's key schedule rotate operation
 | 
			
		||||
 * rotate the word eight bits to the left
 | 
			
		||||
 *
 | 
			
		||||
 * rotate(1d2c3a4f) = 2c3a4f1d
 | 
			
		||||
 *
 | 
			
		||||
 * word is an char array of size 4 (32 bit)
 | 
			
		||||
 */
 | 
			
		||||
void rotate(unsigned char *word)
 | 
			
		||||
{
 | 
			
		||||
    unsigned char c;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    c = word[0];
 | 
			
		||||
    for (i = 0; i < 3; i++)
 | 
			
		||||
        word[i] = word[i+1];
 | 
			
		||||
    word[3] = c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned char getRconValue(unsigned char num)
 | 
			
		||||
{
 | 
			
		||||
	return Rcon[num];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void core(unsigned char *word, int iteration)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	/* rotate the 32-bit word 8 bits to the left */
 | 
			
		||||
	rotate(word);
 | 
			
		||||
 | 
			
		||||
	/* apply S-Box substitution on all 4 parts of the 32-bit word */
 | 
			
		||||
	for (i = 0; i < 4; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		word[i] = getSBoxValue(word[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* XOR the output of the rcon operation with i to the first part (leftmost) only */
 | 
			
		||||
	word[0] = word[0]^getRconValue(((unsigned char) iteration));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Rijndael's key expansion
 | 
			
		||||
 * expands an 128,192,256 key into an 176,208,240 bytes key
 | 
			
		||||
 *
 | 
			
		||||
 * expandedKey is a pointer to an char array of large enough size
 | 
			
		||||
 * key is a pointer to a non-expanded key
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void expandKey(unsigned char *expandedKey,
 | 
			
		||||
               unsigned char *key,
 | 
			
		||||
               enum keySize size,
 | 
			
		||||
               /*size_t*/ unsigned int expandedKeySize)
 | 
			
		||||
{
 | 
			
		||||
    /* current expanded keySize, in bytes */
 | 
			
		||||
    int currentSize = 0;
 | 
			
		||||
    int rconIteration = 1;
 | 
			
		||||
    int i;
 | 
			
		||||
    unsigned char t[4] = {0,0,0,0};   // temporary 4-byte variable
 | 
			
		||||
 | 
			
		||||
    /* set the 16,24,32 bytes of the expanded key to the input key */
 | 
			
		||||
    for (i = 0; i < size; i++)
 | 
			
		||||
        expandedKey[i] = key[i];
 | 
			
		||||
    currentSize += size;
 | 
			
		||||
 | 
			
		||||
    while (currentSize < expandedKeySize)
 | 
			
		||||
    {
 | 
			
		||||
        /* assign the previous 4 bytes to the temporary value t */
 | 
			
		||||
        for (i = 0; i < 4; i++)
 | 
			
		||||
        {
 | 
			
		||||
            t[i] = expandedKey[(currentSize - 4) + i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* every 16,24,32 bytes we apply the core schedule to t
 | 
			
		||||
         * and increment rconIteration afterwards
 | 
			
		||||
         */
 | 
			
		||||
        if(currentSize % size == 0)
 | 
			
		||||
        {
 | 
			
		||||
            core(t, rconIteration++);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* For 256-bit keys, we add an extra sbox to the calculation */
 | 
			
		||||
        if(size == SIZE_32 && ((currentSize % size) == 16)) {
 | 
			
		||||
            for(i = 0; i < 4; i++)
 | 
			
		||||
                t[i] = getSBoxValue(t[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
 | 
			
		||||
         * This becomes the next four bytes in the expanded key.
 | 
			
		||||
         */
 | 
			
		||||
        for(i = 0; i < 4; i++) {
 | 
			
		||||
            expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[i];
 | 
			
		||||
            currentSize++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Encrypt
 | 
			
		||||
 | 
			
		||||
void subBytes(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    /* substitute all the values from the state with the value in the SBox
 | 
			
		||||
     * using the state value as index for the SBox
 | 
			
		||||
     */
 | 
			
		||||
    for (i = 0; i < 16; i++)
 | 
			
		||||
        state[i] = getSBoxValue(state[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shiftRow(unsigned char *state, unsigned char nbr)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	unsigned char tmp;
 | 
			
		||||
	/* each iteration shifts the row to the left by 1 */
 | 
			
		||||
	for (i = 0; i < nbr; i++)
 | 
			
		||||
	{
 | 
			
		||||
		tmp = state[0];
 | 
			
		||||
		for (j = 0; j < 3; j++)
 | 
			
		||||
		state[j] = state[j+1];
 | 
			
		||||
		state[3] = tmp;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void shiftRows(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	/* iterate over the 4 rows and call shiftRow() with that row */
 | 
			
		||||
	for (i = 0; i < 4; i++)
 | 
			
		||||
	shiftRow(state+i*4, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void addRoundKey(unsigned char *state, unsigned char *roundKey)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 0; i < 16; i++)
 | 
			
		||||
	state[i] = state[i] ^ roundKey[i] ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned char galois_multiplication(unsigned char a, unsigned char b)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char p = 0;
 | 
			
		||||
	unsigned char counter;
 | 
			
		||||
	unsigned char hi_bit_set;
 | 
			
		||||
	for(counter = 0; counter < 8; counter++) {
 | 
			
		||||
		if((b & 1) == 1)
 | 
			
		||||
			p ^= a;
 | 
			
		||||
		hi_bit_set = (a & 0x80);
 | 
			
		||||
		a <<= 1;
 | 
			
		||||
		if(hi_bit_set == 0x80)
 | 
			
		||||
			a ^= 0x1b;
 | 
			
		||||
		b >>= 1;
 | 
			
		||||
	}
 | 
			
		||||
	return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mixColumn(unsigned char *column)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char cpy[4];
 | 
			
		||||
	int i;
 | 
			
		||||
	for(i = 0; i < 4; i++)
 | 
			
		||||
	{
 | 
			
		||||
		cpy[i] = column[i];
 | 
			
		||||
	}
 | 
			
		||||
	column[0] = galois_multiplication(cpy[0],2) ^
 | 
			
		||||
	galois_multiplication(cpy[3],1) ^
 | 
			
		||||
	galois_multiplication(cpy[2],1) ^
 | 
			
		||||
	galois_multiplication(cpy[1],3);
 | 
			
		||||
 | 
			
		||||
	column[1] = galois_multiplication(cpy[1],2) ^
 | 
			
		||||
	galois_multiplication(cpy[0],1) ^
 | 
			
		||||
	galois_multiplication(cpy[3],1) ^
 | 
			
		||||
	galois_multiplication(cpy[2],3);
 | 
			
		||||
 | 
			
		||||
	column[2] = galois_multiplication(cpy[2],2) ^
 | 
			
		||||
	galois_multiplication(cpy[1],1) ^
 | 
			
		||||
	galois_multiplication(cpy[0],1) ^
 | 
			
		||||
	galois_multiplication(cpy[3],3);
 | 
			
		||||
 | 
			
		||||
	column[3] = galois_multiplication(cpy[3],2) ^
 | 
			
		||||
	galois_multiplication(cpy[2],1) ^
 | 
			
		||||
	galois_multiplication(cpy[1],1) ^
 | 
			
		||||
	galois_multiplication(cpy[0],3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mixColumns(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	unsigned char column[4];
 | 
			
		||||
 | 
			
		||||
	/* iterate over the 4 columns */
 | 
			
		||||
	for (i = 0; i < 4; i++)
 | 
			
		||||
	{
 | 
			
		||||
		/* construct one column by iterating over the 4 rows */
 | 
			
		||||
		for (j = 0; j < 4; j++)
 | 
			
		||||
		{
 | 
			
		||||
			column[j] = state[(j*4)+i];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* apply the mixColumn on one column */
 | 
			
		||||
		mixColumn(column);
 | 
			
		||||
 | 
			
		||||
		/* put the values back into the state */
 | 
			
		||||
		for (j = 0; j < 4; j++)
 | 
			
		||||
		{
 | 
			
		||||
			state[(j*4)+i] = column[j];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void aes_round(unsigned char *state, unsigned char *roundKey)
 | 
			
		||||
{
 | 
			
		||||
	subBytes(state);
 | 
			
		||||
	shiftRows(state);
 | 
			
		||||
	mixColumns(state);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void createRoundKey(unsigned char *expandedKey, unsigned char *roundKey)
 | 
			
		||||
{
 | 
			
		||||
	int i,j;
 | 
			
		||||
	/* iterate over the columns */
 | 
			
		||||
	for (i = 0; i < 4; i++)
 | 
			
		||||
	{
 | 
			
		||||
		/* iterate over the rows */
 | 
			
		||||
		for (j = 0; j < 4; j++)
 | 
			
		||||
		roundKey[(i+(j*4))] = expandedKey[(i*4)+j];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void aes_main(unsigned char *state, unsigned char *expandedKey, int nbrRounds)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	unsigned char roundKey[16];
 | 
			
		||||
 | 
			
		||||
	createRoundKey(expandedKey, roundKey);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
 | 
			
		||||
	for (i = 1; i < nbrRounds; i++) {
 | 
			
		||||
		createRoundKey(expandedKey + 16*i, roundKey);
 | 
			
		||||
		aes_round(state, roundKey);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createRoundKey(expandedKey + 16*nbrRounds, roundKey);
 | 
			
		||||
	subBytes(state);
 | 
			
		||||
	shiftRows(state);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char aes_encrypt(unsigned char *input,
 | 
			
		||||
                 unsigned char *output,
 | 
			
		||||
                 unsigned char *key
 | 
			
		||||
                 /*, enum keySize size*/)
 | 
			
		||||
{
 | 
			
		||||
	enum keySize size = SIZE_16;
 | 
			
		||||
    /* the expanded keySize */
 | 
			
		||||
    int expandedKeySize;
 | 
			
		||||
 | 
			
		||||
    /* the number of rounds */
 | 
			
		||||
    int nbrRounds = 10;	//NOTE: modded
 | 
			
		||||
 | 
			
		||||
    /* the expanded key */
 | 
			
		||||
    //NOTE: modded: unsigned char *expandedKey = 0x00;
 | 
			
		||||
	//unsigned char expandedKey[(16*(nbrRounds+1))];
 | 
			
		||||
	unsigned char expandedKey[176];
 | 
			
		||||
 | 
			
		||||
    /* the 128 bit block to encode */
 | 
			
		||||
    unsigned char block[16];
 | 
			
		||||
 | 
			
		||||
    int i,j;
 | 
			
		||||
 | 
			
		||||
    /* set the number of rounds */
 | 
			
		||||
    /*switch (size)
 | 
			
		||||
    {
 | 
			
		||||
        case SIZE_16:
 | 
			
		||||
            nbrRounds = 10;
 | 
			
		||||
            break;
 | 
			
		||||
        case SIZE_24:
 | 
			
		||||
            nbrRounds = 12;
 | 
			
		||||
            break;
 | 
			
		||||
        case SIZE_32:
 | 
			
		||||
            nbrRounds = 14;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return 1; //UNKNOWN_KEYSIZE;
 | 
			
		||||
            break;
 | 
			
		||||
    }*/ //NOTE: modded
 | 
			
		||||
 | 
			
		||||
    expandedKeySize = (16*(nbrRounds+1));
 | 
			
		||||
    /*if ((expandedKey = malloc(expandedKeySize * sizeof(char))) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return MEMORY_ALLOCATION_PROBLEM;
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    /* Set the block values, for the block:
 | 
			
		||||
     * a0,0 a0,1 a0,2 a0,3
 | 
			
		||||
     * a1,0 a1,1 a1,2 a1,3
 | 
			
		||||
     * a2,0 a2,1 a2,2 a2,3
 | 
			
		||||
     * a3,0 a3,1 a3,2 a3,3
 | 
			
		||||
     * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* iterate over the columns */
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
        /* iterate over the rows */
 | 
			
		||||
        for (j = 0; j < 4; j++)
 | 
			
		||||
            block[(i+(j*4))] = input[(i*4)+j];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* expand the key into an 176, 208, 240 bytes key */
 | 
			
		||||
    expandKey(expandedKey, key, size, expandedKeySize);
 | 
			
		||||
 | 
			
		||||
    /* encrypt the block using the expandedKey */
 | 
			
		||||
    aes_main(block, expandedKey, nbrRounds);
 | 
			
		||||
 | 
			
		||||
    /* unmap the block again into the output */
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
        /* iterate over the rows */
 | 
			
		||||
        for (j = 0; j < 4; j++)
 | 
			
		||||
            output[(i*4)+j] = block[(i+(j*4))];
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Decrypt
 | 
			
		||||
void invSubBytes(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    /* substitute all the values from the state with the value in the SBox
 | 
			
		||||
     * using the state value as index for the SBox
 | 
			
		||||
     */
 | 
			
		||||
    for (i = 0; i < 16; i++)
 | 
			
		||||
        state[i] = getSBoxInvert(state[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void invShiftRow(unsigned char *state, unsigned char nbr)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	unsigned char tmp;
 | 
			
		||||
	/* each iteration shifts the row to the right by 1 */
 | 
			
		||||
	for (i = 0; i < nbr; i++)
 | 
			
		||||
	{
 | 
			
		||||
		tmp = state[3];
 | 
			
		||||
		for (j = 3; j > 0; j--)
 | 
			
		||||
		state[j] = state[j-1];
 | 
			
		||||
		state[0] = tmp;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void invShiftRows(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    /* iterate over the 4 rows and call invShiftRow() with that row */
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
        invShiftRow(state+i*4, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void invMixColumn(unsigned char *column)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char cpy[4];
 | 
			
		||||
	int i;
 | 
			
		||||
	for(i = 0; i < 4; i++)
 | 
			
		||||
	{
 | 
			
		||||
		cpy[i] = column[i];
 | 
			
		||||
	}
 | 
			
		||||
	column[0] = galois_multiplication(cpy[0],14) ^
 | 
			
		||||
	galois_multiplication(cpy[3],9) ^
 | 
			
		||||
	galois_multiplication(cpy[2],13) ^
 | 
			
		||||
	galois_multiplication(cpy[1],11);
 | 
			
		||||
	column[1] = galois_multiplication(cpy[1],14) ^
 | 
			
		||||
	galois_multiplication(cpy[0],9) ^
 | 
			
		||||
	galois_multiplication(cpy[3],13) ^
 | 
			
		||||
	galois_multiplication(cpy[2],11);
 | 
			
		||||
	column[2] = galois_multiplication(cpy[2],14) ^
 | 
			
		||||
	galois_multiplication(cpy[1],9) ^
 | 
			
		||||
	galois_multiplication(cpy[0],13) ^
 | 
			
		||||
	galois_multiplication(cpy[3],11);
 | 
			
		||||
	column[3] = galois_multiplication(cpy[3],14) ^
 | 
			
		||||
	galois_multiplication(cpy[2],9) ^
 | 
			
		||||
	galois_multiplication(cpy[1],13) ^
 | 
			
		||||
	galois_multiplication(cpy[0],11);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void invMixColumns(unsigned char *state)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	unsigned char column[4];
 | 
			
		||||
 | 
			
		||||
	/* iterate over the 4 columns */
 | 
			
		||||
	for (i = 0; i < 4; i++)
 | 
			
		||||
	{
 | 
			
		||||
		/* construct one column by iterating over the 4 rows */
 | 
			
		||||
		for (j = 0; j < 4; j++)
 | 
			
		||||
		{
 | 
			
		||||
			column[j] = state[(j*4)+i];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* apply the invMixColumn on one column */
 | 
			
		||||
		invMixColumn(column);
 | 
			
		||||
 | 
			
		||||
		/* put the values back into the state */
 | 
			
		||||
		for (j = 0; j < 4; j++)
 | 
			
		||||
		{
 | 
			
		||||
			state[(j*4)+i] = column[j];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void aes_invRound(unsigned char *state, unsigned char *roundKey)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	invShiftRows(state);
 | 
			
		||||
	invSubBytes(state);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
	invMixColumns(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void aes_invMain(unsigned char *state, unsigned char *expandedKey, int nbrRounds)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	unsigned char roundKey[16];
 | 
			
		||||
 | 
			
		||||
	createRoundKey(expandedKey + 16*nbrRounds, roundKey);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
 | 
			
		||||
	for (i = nbrRounds-1; i > 0; i--) {
 | 
			
		||||
		createRoundKey(expandedKey + 16*i, roundKey);
 | 
			
		||||
		aes_invRound(state, roundKey);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	createRoundKey(expandedKey, roundKey);
 | 
			
		||||
	invShiftRows(state);
 | 
			
		||||
	invSubBytes(state);
 | 
			
		||||
	addRoundKey(state, roundKey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char aes_decrypt(unsigned char *input,
 | 
			
		||||
                 unsigned char *output,
 | 
			
		||||
                 unsigned char *key
 | 
			
		||||
                 /*´, enum keySize size*/)
 | 
			
		||||
{
 | 
			
		||||
	enum keySize size = SIZE_16;
 | 
			
		||||
    /* the expanded keySize */
 | 
			
		||||
    int expandedKeySize;
 | 
			
		||||
 | 
			
		||||
    /* the number of rounds */
 | 
			
		||||
    int nbrRounds;
 | 
			
		||||
 | 
			
		||||
    /* the expanded key */
 | 
			
		||||
    unsigned char *expandedKey = 0x00;
 | 
			
		||||
 | 
			
		||||
    /* the 128 bit block to decode */
 | 
			
		||||
    unsigned char block[16];
 | 
			
		||||
 | 
			
		||||
    int i,j;
 | 
			
		||||
 | 
			
		||||
    /* set the number of rounds */
 | 
			
		||||
    switch (size)
 | 
			
		||||
    {
 | 
			
		||||
        case SIZE_16:
 | 
			
		||||
            nbrRounds = 10;
 | 
			
		||||
            break;
 | 
			
		||||
        case SIZE_24:
 | 
			
		||||
            nbrRounds = 12;
 | 
			
		||||
            break;
 | 
			
		||||
        case SIZE_32:
 | 
			
		||||
            nbrRounds = 14;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return 1; //UNKNOWN_KEYSIZE;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expandedKeySize = (16*(nbrRounds+1));
 | 
			
		||||
    /*if ((expandedKey = malloc(expandedKeySize * sizeof(char))) == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return MEMORY_ALLOCATION_PROBLEM;
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    /* Set the block values, for the block:
 | 
			
		||||
     * a0,0 a0,1 a0,2 a0,3
 | 
			
		||||
     * a1,0 a1,1 a1,2 a1,3
 | 
			
		||||
     * a2,0 a2,1 a2,2 a2,3
 | 
			
		||||
     * a3,0 a3,1 a3,2 a3,3
 | 
			
		||||
     * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /* iterate over the columns */
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
        /* iterate over the rows */
 | 
			
		||||
        for (j = 0; j < 4; j++)
 | 
			
		||||
            block[(i+(j*4))] = input[(i*4)+j];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* expand the key into an 176, 208, 240 bytes key */
 | 
			
		||||
    expandKey(expandedKey, key, size, expandedKeySize);
 | 
			
		||||
 | 
			
		||||
    /* decrypt the block using the expandedKey */
 | 
			
		||||
    aes_invMain(block, expandedKey, nbrRounds);
 | 
			
		||||
 | 
			
		||||
    /* unmap the block again into the output */
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
        /* iterate over the rows */
 | 
			
		||||
        for (j = 0; j < 4; j++)
 | 
			
		||||
            output[(i*4)+j] = block[(i+(j*4))];
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
#ifndef AES128_H
 | 
			
		||||
#define AES128_H
 | 
			
		||||
 | 
			
		||||
void aes_init();
 | 
			
		||||
char aes_encrypt(unsigned char *input,unsigned char *output,unsigned char *key);
 | 
			
		||||
char aes_decrypt(unsigned char *input,unsigned char *output,unsigned char *key);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										491
									
								
								main/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										491
									
								
								main/main.cpp
									
									
									
									
									
								
							@@ -35,7 +35,6 @@ extern "C" char* strptime(const char* s,
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include "calculator_functions.h"
 | 
			
		||||
#include "calculate_price.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#define SZEGED                                  (0)
 | 
			
		||||
#define SCHOENAU_KOENIGSEE                      (0)
 | 
			
		||||
@@ -46,9 +45,7 @@ extern "C" char* strptime(const char* s,
 | 
			
		||||
#define BAD_NEUENAHR_AHRWEILER                  (0)
 | 
			
		||||
#define NEUHAUSER_CHRISTOPH_REISEN              (0)
 | 
			
		||||
#define NEUHAUSER_PERNEGG_AN_DER_MUR            (0)
 | 
			
		||||
#define NEUHAUSER_STOCKERAU                     (0)
 | 
			
		||||
#define KLEIPEDA_LITAUEN                        (0)
 | 
			
		||||
#define SEXTEN                                  (1)
 | 
			
		||||
#define NEUHAUSER_STOCKERAU                     (1)
 | 
			
		||||
 | 
			
		||||
#if NEUHAUSER_KIRCHDORF==1
 | 
			
		||||
static bool test_neuhauser_kirchdorf(int step, double cost) {
 | 
			
		||||
@@ -169,457 +166,8 @@ static bool test_neuhauser_kirchdorf(int step, double cost) {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <QJsonArray>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QJsonValue>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    QJsonObject root;
 | 
			
		||||
    QJsonArray PaymentRate;
 | 
			
		||||
    QJsonArray Duration;
 | 
			
		||||
 | 
			
		||||
    for (int i = 1; i <= 15*15; ++i) {
 | 
			
		||||
        QJsonObject o;
 | 
			
		||||
        o["pra_payment_option_id"] = 1049;
 | 
			
		||||
        o["pra_payment_unit_id"] = i;
 | 
			
		||||
        if (i <= 15) {
 | 
			
		||||
            o["pra_price"] = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            o["pra_price"] = (i-15)*10;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PaymentRate.push_back(o);
 | 
			
		||||
    }
 | 
			
		||||
    for (int i = 1; i <= 15*15; ++i) {
 | 
			
		||||
        QJsonObject o;
 | 
			
		||||
        o["pun_duration"] = i*4;
 | 
			
		||||
        o["pun_id"] = i;
 | 
			
		||||
        o["pun_label"] = QString("%1 min").arg(i*4);
 | 
			
		||||
        Duration.push_back(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    root["PaymentRate"] = PaymentRate;
 | 
			
		||||
    root["Duration"] = Duration;
 | 
			
		||||
 | 
			
		||||
    qCritical().noquote() << QJsonDocument(root).toJson();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
#if 0
 | 
			
		||||
 | 
			
		||||
    MessageHelper msgHelp;
 | 
			
		||||
    // msgHelp.createLoginMessageChunksToSend(0x02);
 | 
			
		||||
    msgHelp.createAuthorizeMessageChunksToSend(0x02);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    qCritical() << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << endl;
 | 
			
		||||
 | 
			
		||||
    // unsigned static char terminalID[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
 | 
			
		||||
    // unsigned static char terminalAPAK[IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE];
 | 
			
		||||
    strncpy((char *)&terminalID[0], "T-TPS-SELF2002in", IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE);
 | 
			
		||||
    strncpy((char *)&terminalAPAK[0], "8AC304380E0E476BA2558B75DB9E2516", IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE);
 | 
			
		||||
 | 
			
		||||
    //iuc_asynchpos_command_Login();
 | 
			
		||||
    iuc_asynchpos_command_authorize(1000);
 | 
			
		||||
 | 
			
		||||
    qCritical() << "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
    // test aes
 | 
			
		||||
    aes_init();
 | 
			
		||||
 | 
			
		||||
    uint32_t crc = 0;
 | 
			
		||||
 | 
			
		||||
    QByteArray a("T-TPS-SELF2002");
 | 
			
		||||
    qCritical() << a.toHex(' ');
 | 
			
		||||
 | 
			
		||||
    //QByteArray xx("\x0D\x54\x2D\x54\x50\x53\x2D\x53\x45\x4C\x46\x32\x30\x30\x32\x85\x4C\x6F\x67\x69\x6E\x04\x54\x69\x6D\x65\x00\x13\x32\x30\x32\x34\x2d\x30\x36\x2d\x31\x31\x20\x31\x33\x3a\x34\x34\x3a\x33\x35\x00\x02",
 | 
			
		||||
    //              48);
 | 
			
		||||
 | 
			
		||||
    //QByteArray xx("123456789", 9);
 | 
			
		||||
 | 
			
		||||
    QByteArray xx("2E5450532D53454C4632303032854C6F67696E0454696D650013323032342d30362d31312031333a34343a333505466C616773000341505300",
 | 
			
		||||
                  114);
 | 
			
		||||
    unsigned char bb = 0;
 | 
			
		||||
    //32:4b:e7:4e:1d:d7:b5:ae
 | 
			
		||||
    QByteArray b("\x00\x46\x00\x32\x4b\xe7\x4e\x1d\xd7\xb5\xae\x0E\x54\x2D\x54\x50\x53\x2D\x53\x45\x4C\x46\x32\x30\x30\x32\x85\x4C\x6F\x67\x69\x6E\x04\x54\x69\x6D\x65\x00\x13\x32\x30\x32\x34\x2d\x30\x36\x2d\x31\x31\x20\x31\x33\x3a\x34\x34\x3a\x33\x35\x05\x46\x6C\x61\x67\x73\x00\x03\x41\x50\x53\x00\x02",
 | 
			
		||||
                 71);
 | 
			
		||||
    qCritical() << "B" << b.toHex(':');
 | 
			
		||||
 | 
			
		||||
    for (int i=0; i < b.size(); ++i) {
 | 
			
		||||
        //printf("%d %02x\n", i, (unsigned char)b.at(i));
 | 
			
		||||
        bb = bb ^ b.at(i);
 | 
			
		||||
    }
 | 
			
		||||
    printf("bb=%02x\n", bb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    qCritical() << xx.size() << "xx" << xx.toHex(' ');
 | 
			
		||||
 | 
			
		||||
    crc = iuc_asynchpos_sub_updateCRC(crc, xx.data(), xx.size());
 | 
			
		||||
 | 
			
		||||
    printf("111 crc=%04x\n", crc);
 | 
			
		||||
 | 
			
		||||
    crc = crc32(xx.data(), xx.size());
 | 
			
		||||
    printf("222 crc=%04x\n", crc);
 | 
			
		||||
 | 
			
		||||
    QByteArray ba("TEST\x0E\x0E\x47\x6B\xA2\x55\x8B\x75\xDB\x9E\x25\x16");
 | 
			
		||||
 | 
			
		||||
    ba[0] = (crc >> 24);
 | 
			
		||||
    ba[1] = (crc >> 16);
 | 
			
		||||
    ba[2] = (crc >> 8);
 | 
			
		||||
    ba[3] = (crc);
 | 
			
		||||
 | 
			
		||||
    qCritical() << ba.toHex(' ');
 | 
			
		||||
 | 
			
		||||
    QDateTime current = QDateTime::currentDateTime();
 | 
			
		||||
    QString const &s = current.toString(Qt::ISODate);
 | 
			
		||||
    QByteArray time(s.toStdString().c_str());
 | 
			
		||||
    time[10] = ' ';
 | 
			
		||||
 | 
			
		||||
    qCritical() << time.toHex(' ');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //unsigned char in[] = "TESTTESTTESTTEST";
 | 
			
		||||
    //unsigned char in[] = ba.data();
 | 
			
		||||
    unsigned char key[]  = "8AC304380E0E476BA2558B75DB9E2516";
 | 
			
		||||
    //unsigned char key[] = "\x8A\xC3\x04\x38\x0E\x0E\x47\x6B\xA2\x55\x8B\x75\xDB\x9E\x25\x16";
 | 
			
		||||
    unsigned char output[256];
 | 
			
		||||
 | 
			
		||||
    memset(output, 0, sizeof(output));
 | 
			
		||||
 | 
			
		||||
    aes_encrypt((unsigned char*)ba.data(), output, key);
 | 
			
		||||
 | 
			
		||||
    qCritical() << ba.toHex(':') << endl;
 | 
			
		||||
    qCritical() << QByteArray((char*)key).toHex(':') << endl;
 | 
			
		||||
    qCritical() << QByteArray((char*)output).toHex(':') << endl;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//char aes_encrypt(unsigned char *input,unsigned char *output,unsigned char *key);
 | 
			
		||||
 | 
			
		||||
#if KLEIPEDA_LITAUEN==1
 | 
			
		||||
    std::ifstream input;
 | 
			
		||||
    int pop_min_time;
 | 
			
		||||
    int pop_max_time;
 | 
			
		||||
    int pop_min_price;
 | 
			
		||||
    int pop_max_price;
 | 
			
		||||
    int pop_daily_card_price;
 | 
			
		||||
 | 
			
		||||
    input.open("/opt/ptu5/opt/customer_335/etc/psa_tariff/tariff01.json");
 | 
			
		||||
 | 
			
		||||
    std::stringstream sstr;
 | 
			
		||||
    while(input >> sstr.rdbuf());
 | 
			
		||||
    std::string json(sstr.str());
 | 
			
		||||
 | 
			
		||||
    Configuration cfg;
 | 
			
		||||
 | 
			
		||||
    bool isParsed = cfg.ParseJson(&cfg, json.c_str());
 | 
			
		||||
    cout << endl;
 | 
			
		||||
 | 
			
		||||
    if (isParsed) {
 | 
			
		||||
        pop_min_time = get_minimal_parkingtime(&cfg);
 | 
			
		||||
        pop_max_time = get_maximal_parkingtime(&cfg);
 | 
			
		||||
        pop_min_price = get_minimal_parkingprice(&cfg);
 | 
			
		||||
        pop_max_price = get_maximal_parkingprice(&cfg);
 | 
			
		||||
        pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price;
 | 
			
		||||
 | 
			
		||||
        qCritical() << "        pop_min_time: " << pop_min_time;
 | 
			
		||||
        qCritical() << "        pop_max_time: " << pop_max_time;
 | 
			
		||||
        qCritical() << "       pop_min_price: " << pop_min_price;
 | 
			
		||||
        qCritical() << "       pop_max_price: " << pop_max_price;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        QList<int> timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg);
 | 
			
		||||
        qCritical() << "TimeSteps" << timeSteps;
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
        CalcState cs;
 | 
			
		||||
        double cost;
 | 
			
		||||
        int durationInMinutes = 0;
 | 
			
		||||
        int offsetInMinutes = 0;
 | 
			
		||||
 | 
			
		||||
        // for (int day = Qt::Monday; day <= Qt::Sunday; ++day) {
 | 
			
		||||
        for (int day = Qt::Monday; day <= Qt::Monday; ++day) {
 | 
			
		||||
            QDateTime s(QDate(2024, 5, 19 + day), QTime()); // 20: (whit) monday,..., 26: sunday
 | 
			
		||||
            QDateTime end;
 | 
			
		||||
 | 
			
		||||
            switch (day) {
 | 
			
		||||
            case (int)Qt::Monday:
 | 
			
		||||
                qCritical() << "Monday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Tuesday:
 | 
			
		||||
                qCritical() << "Tuesday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Wednesday:
 | 
			
		||||
                qCritical() << "Wednesday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Thursday:
 | 
			
		||||
                qCritical() << "Thursday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Friday:
 | 
			
		||||
                qCritical() << "Friday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Saturday:
 | 
			
		||||
                qCritical() << "Saturday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Sunday:
 | 
			
		||||
                qCritical() << "Sunday";
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
            CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
 | 
			
		||||
                                                        parking_tariff_t *tariff,
 | 
			
		||||
                                                        QDateTime &start_parking_time,
 | 
			
		||||
                                                        int netto_parking_time,
 | 
			
		||||
                                                        QDateTime &end_parking_time,    // return value
 | 
			
		||||
                                                        struct price_t *price,          // return value
 | 
			
		||||
                                                        bool prepaid = true);
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            for (int minutes = 0; minutes < 1440; ++minutes) {
 | 
			
		||||
                QDateTime start = s.addSecs(minutes * 60);
 | 
			
		||||
                QDateTime effectiveStart = start;
 | 
			
		||||
 | 
			
		||||
                if (start.time() < QTime(8, 0, 0)) {
 | 
			
		||||
                    effectiveStart.setTime(QTime(8, 0, 0));
 | 
			
		||||
                } else
 | 
			
		||||
                if (start.time() <= QTime(22, 0, 0)) {
 | 
			
		||||
                    effectiveStart = start;
 | 
			
		||||
                } else {
 | 
			
		||||
                    effectiveStart = start.addDays(1);
 | 
			
		||||
                    effectiveStart.setTime(QTime(8, 0, 0)); // next day
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i <= 2100; i += 10) {
 | 
			
		||||
                //for (int i = 2100; i <= 2100; i += 10) {
 | 
			
		||||
                    cost = i;
 | 
			
		||||
 | 
			
		||||
                    if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end))) {      // return value
 | 
			
		||||
                        durationInMinutes = pop_min_time;
 | 
			
		||||
                        if (i > 0) {
 | 
			
		||||
                            durationInMinutes += (i/10) * 4;
 | 
			
		||||
                        }
 | 
			
		||||
                        offsetInMinutes = 0;
 | 
			
		||||
 | 
			
		||||
                        if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(22, 0, 0)) {
 | 
			
		||||
                            if (effectiveStart.time().secsTo(QTime(22, 0, 0)) < (durationInMinutes * 60)) {
 | 
			
		||||
                                offsetInMinutes = 600; // 22:00 -> 8:00
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (i == 0) {
 | 
			
		||||
                            i += 20;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if ((durationInMinutes + offsetInMinutes) == (effectiveStart.secsTo(end) / 60)) {
 | 
			
		||||
 | 
			
		||||
                            if (day == Qt::Monday && minutes >= 480 && minutes <= 1320) {
 | 
			
		||||
                                qCritical() << "| start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                                qCritical() << "| cost ............................." << cost;
 | 
			
		||||
                                qCritical() << "| durationInMinutes ................" << durationInMinutes
 | 
			
		||||
                                            << "(" << (durationInMinutes - 60) << "+ 60 )";
 | 
			
		||||
                                qCritical() << "| offsetInMinutes .................." << offsetInMinutes;
 | 
			
		||||
                                qCritical() << "| end .............................." << end.toString(Qt::ISODate) << endl;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!cs) {
 | 
			
		||||
                        qCritical() << "ERROR CalcState" << cs.toString() << endl;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        qCritical() << cs.toString();
 | 
			
		||||
                    }
 | 
			
		||||
                    qCritical() << __LINE__ << "start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << __LINE__ << "effectiveStart ..................." << effectiveStart.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << __LINE__ << "cost ............................." << cost;
 | 
			
		||||
                    qCritical() << __LINE__ << "durationInMinutes ................" << durationInMinutes;
 | 
			
		||||
                    qCritical() << __LINE__ << "offsetInMinutes .................." << offsetInMinutes;
 | 
			
		||||
                    qCritical() << __LINE__ << "effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60;
 | 
			
		||||
                    qCritical() << __LINE__ << "end .............................." << end.toString(Qt::ISODate) << endl;
 | 
			
		||||
                    exit(-1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if SEXTEN==1
 | 
			
		||||
    std::ifstream input;
 | 
			
		||||
    int pop_min_time;
 | 
			
		||||
    int pop_max_time;
 | 
			
		||||
    int pop_min_price;
 | 
			
		||||
    int pop_max_price;
 | 
			
		||||
    int pop_daily_card_price;
 | 
			
		||||
 | 
			
		||||
    input.open("/opt/ptu5/opt/customer_501/etc/psa_tariff/tariff01.json");
 | 
			
		||||
 | 
			
		||||
    std::stringstream sstr;
 | 
			
		||||
    while(input >> sstr.rdbuf());
 | 
			
		||||
    std::string json(sstr.str());
 | 
			
		||||
 | 
			
		||||
    Configuration cfg;
 | 
			
		||||
 | 
			
		||||
    bool isParsed = cfg.ParseJson(&cfg, json.c_str());
 | 
			
		||||
    cout << endl;
 | 
			
		||||
 | 
			
		||||
    if (isParsed) {
 | 
			
		||||
        pop_min_time = get_minimal_parkingtime(&cfg);
 | 
			
		||||
        pop_max_time = get_maximal_parkingtime(&cfg);
 | 
			
		||||
        pop_min_price = get_minimal_parkingprice(&cfg);
 | 
			
		||||
        pop_max_price = get_maximal_parkingprice(&cfg);
 | 
			
		||||
        pop_daily_card_price = cfg.getPaymentOptions().pop_daily_card_price;
 | 
			
		||||
 | 
			
		||||
        qCritical() << "        pop_min_time: " << pop_min_time;
 | 
			
		||||
        qCritical() << "        pop_max_time: " << pop_max_time;
 | 
			
		||||
        qCritical() << "       pop_min_price: " << pop_min_price;
 | 
			
		||||
        qCritical() << "       pop_max_price: " << pop_max_price;
 | 
			
		||||
 | 
			
		||||
        QList<int> timeSteps = Calculator::GetInstance().GetTimeSteps(&cfg);
 | 
			
		||||
        qCritical() << "TimeSteps" << timeSteps;
 | 
			
		||||
 | 
			
		||||
        // return 0;
 | 
			
		||||
 | 
			
		||||
        CalcState cs;
 | 
			
		||||
        double cost;
 | 
			
		||||
        int durationInMinutes = 0;
 | 
			
		||||
        int offsetInMinutes = 0;
 | 
			
		||||
 | 
			
		||||
        // for (int day = Qt::Monday; day <= Qt::Sunday; ++day) {
 | 
			
		||||
        for (int day = Qt::Monday; day <= Qt::Monday; ++day) {
 | 
			
		||||
            QDateTime s(QDate(2024, 7, 14 + day), QTime()); // 20: (whit) monday,..., 26: sunday
 | 
			
		||||
            QDateTime end;
 | 
			
		||||
 | 
			
		||||
            switch (day) {
 | 
			
		||||
            case (int)Qt::Monday:
 | 
			
		||||
                qCritical() << "Monday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Tuesday:
 | 
			
		||||
                qCritical() << "Tuesday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Wednesday:
 | 
			
		||||
                qCritical() << "Wednesday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Thursday:
 | 
			
		||||
                qCritical() << "Thursday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Friday:
 | 
			
		||||
                qCritical() << "Friday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Saturday:
 | 
			
		||||
                qCritical() << "Saturday";
 | 
			
		||||
                break;
 | 
			
		||||
            case (int)Qt::Sunday:
 | 
			
		||||
                qCritical() << "Sunday";
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
            CalcState CALCULATE_LIBRARY_API compute_price_for_parking_ticket(
 | 
			
		||||
                                                        parking_tariff_t *tariff,
 | 
			
		||||
                                                        QDateTime &start_parking_time,
 | 
			
		||||
                                                        int netto_parking_time,
 | 
			
		||||
                                                        QDateTime &end_parking_time,    // return value
 | 
			
		||||
                                                        struct price_t *price,          // return value
 | 
			
		||||
                                                        bool prepaid = true);
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            //for (int minutes = 0; minutes < 1440; ++minutes) {
 | 
			
		||||
            for (int minutes = 480; minutes < 481; minutes += 1) {
 | 
			
		||||
                QDateTime start = s.addSecs(minutes * 60);
 | 
			
		||||
 | 
			
		||||
                qCritical() << "start" << start.toString(Qt::ISODate);
 | 
			
		||||
 | 
			
		||||
                QDateTime effectiveStart = start;
 | 
			
		||||
 | 
			
		||||
                if (start.time() < QTime(8, 0, 0)) {
 | 
			
		||||
                    effectiveStart.setTime(QTime(8, 0, 0));
 | 
			
		||||
                } else
 | 
			
		||||
                if (start.time() <= QTime(19, 0, 0)) {
 | 
			
		||||
                    effectiveStart = start;
 | 
			
		||||
                } else {
 | 
			
		||||
                    effectiveStart = start.addDays(1);
 | 
			
		||||
                    effectiveStart.setTime(QTime(8, 0, 0)); // next day
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                for (int i = 100; i <= 100; i += 10) {
 | 
			
		||||
                //for (int i = 2100; i <= 2100; i += 10) {
 | 
			
		||||
                    cost = i;
 | 
			
		||||
 | 
			
		||||
                    if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end))) {      // return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        qCritical() << "end" << end.toString(Qt::ISODate);
 | 
			
		||||
 | 
			
		||||
                        durationInMinutes = pop_min_time;
 | 
			
		||||
                        if (i > 0) {
 | 
			
		||||
                            durationInMinutes += (i/10) * 4;
 | 
			
		||||
                        }
 | 
			
		||||
                        offsetInMinutes = 0;
 | 
			
		||||
 | 
			
		||||
                        if (effectiveStart.time() >= QTime(8, 0, 0) && effectiveStart.time() <= QTime(19, 0, 0)) {
 | 
			
		||||
                            if (effectiveStart.time().secsTo(QTime(19, 0, 0)) < (durationInMinutes * 60)) {
 | 
			
		||||
                                offsetInMinutes = 780; // 19:00 -> 8:00
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (i == 0) {
 | 
			
		||||
                            i += 20;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
                        if ((durationInMinutes + offsetInMinutes) == (effectiveStart.secsTo(end) / 60)) {
 | 
			
		||||
 | 
			
		||||
                            if (day == Qt::Monday && minutes >= 480 && minutes <= 1140) {
 | 
			
		||||
                                qCritical() << "| start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                                qCritical() << "| cost ............................." << cost;
 | 
			
		||||
                                qCritical() << "| durationInMinutes ................" << durationInMinutes
 | 
			
		||||
                                            << "(" << (durationInMinutes - 60) << "+ 60 )";
 | 
			
		||||
                                qCritical() << "| offsetInMinutes .................." << offsetInMinutes;
 | 
			
		||||
                                qCritical() << "| end .............................." << end.toString(Qt::ISODate) << endl;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
#endif
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!cs) {
 | 
			
		||||
                        qCritical() << "ERROR CalcState" << cs.toString() << endl;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        qCritical() << cs.toString();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
                    qCritical() << __LINE__ << "start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << __LINE__ << "effectiveStart ..................." << effectiveStart.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << __LINE__ << "cost ............................." << cost;
 | 
			
		||||
                    qCritical() << __LINE__ << "durationInMinutes ................" << durationInMinutes;
 | 
			
		||||
                    qCritical() << __LINE__ << "offsetInMinutes .................." << offsetInMinutes;
 | 
			
		||||
                    qCritical() << __LINE__ << "effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60;
 | 
			
		||||
                    qCritical() << __LINE__ << "end .............................." << end.toString(Qt::ISODate) << endl;
 | 
			
		||||
                    exit(-1);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if NEUHAUSER_STOCKERAU==1
 | 
			
		||||
    std::ifstream input;
 | 
			
		||||
    int pop_min_time;
 | 
			
		||||
@@ -651,18 +199,36 @@ int main() {
 | 
			
		||||
        qCritical() << "       pop_min_price: " << pop_min_price;
 | 
			
		||||
        qCritical() << "       pop_max_price: " << pop_max_price;
 | 
			
		||||
 | 
			
		||||
        // tests:
 | 
			
		||||
        // 1: Mon-Freitag: jeweils
 | 
			
		||||
        // start 0-8.00
 | 
			
		||||
        // start 8.00-12.00
 | 
			
		||||
        // start 12.00-13.30
 | 
			
		||||
        // start 13.30-18.00
 | 
			
		||||
        // start 18.00-24.00
 | 
			
		||||
        // alle kosten durchspielen
 | 
			
		||||
        // 2. samstag
 | 
			
		||||
        // start 0-8.00
 | 
			
		||||
        // start 8.00-12.00
 | 
			
		||||
        // start nach 12.00
 | 
			
		||||
        // 2. sonntag
 | 
			
		||||
 | 
			
		||||
        //QDateTime s(QDate(2024, 5, 27), QTime()); // monday
 | 
			
		||||
        //QDateTime s(QDate(2024, 5, 28), QTime()); // tuesday
 | 
			
		||||
        //QDateTime s(QDate(2024, 5, 29), QTime()); // wednesday
 | 
			
		||||
        //QDateTime s(QDate(2024, 5, 30), QTime()); // thursday
 | 
			
		||||
 | 
			
		||||
        CalcState cs;
 | 
			
		||||
        double const x = 30.0/7.0;
 | 
			
		||||
        double cost;
 | 
			
		||||
        int durationInMinutes;
 | 
			
		||||
        int offsetInMinutes = 0;
 | 
			
		||||
 | 
			
		||||
        //for (int day = Qt::Monday; day <= Qt::Sunday; ++day) {
 | 
			
		||||
        for (int day = Qt::Tuesday; day <= Qt::Tuesday; ++day) {
 | 
			
		||||
            QDateTime s(QDate(2024, 6, 9 + day), QTime()); // 20: (whit) monday,..., 26: sunday
 | 
			
		||||
        for (int day = Qt::Monday; day <= Qt::Sunday; ++day) {
 | 
			
		||||
            QDateTime s(QDate(2024, 5, 19 + day), QTime()); // 20: (whit) monday,..., 26: sunday
 | 
			
		||||
            QDateTime end;
 | 
			
		||||
 | 
			
		||||
            for (int minutes = 660; minutes <= 660; ++minutes) {
 | 
			
		||||
            for (int minutes = 0; minutes < 1440; ++minutes) {
 | 
			
		||||
            //for (int minutes = 0; minutes < 1440; ++minutes) {
 | 
			
		||||
                QDateTime start = s.addSecs(minutes * 60);
 | 
			
		||||
                QDateTime effectiveStart = start;
 | 
			
		||||
@@ -700,7 +266,8 @@ int main() {
 | 
			
		||||
                    effectiveStart.setTime(QTime(8,0,0)); // monday
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                for (int i = 700; i <= 700; i += 10) {
 | 
			
		||||
                for (int i = 70; i <= 600; i += 10) {
 | 
			
		||||
                // for (int i = 70; i <= 70; i += 10) {
 | 
			
		||||
                    cost = i;
 | 
			
		||||
                    if ((cs = compute_duration_for_parking_ticket(&cfg, start, cost, end))) {      // return value
 | 
			
		||||
                        durationInMinutes = truncf(x * (i/10));
 | 
			
		||||
@@ -755,13 +322,6 @@ int main() {
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if ((durationInMinutes + offsetInMinutes) == (effectiveStart.secsTo(end) / 60)) {
 | 
			
		||||
                            qCritical() << "| start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                            qCritical() << "| effectiveStart ..................." << effectiveStart.toString(Qt::ISODate);
 | 
			
		||||
                            qCritical() << "| cost ............................." << cost;
 | 
			
		||||
                            qCritical() << "| durationMinutes .................." << durationInMinutes;
 | 
			
		||||
                            qCritical() << "| offsetInMinutes .................." << offsetInMinutes;
 | 
			
		||||
                            qCritical() << "| effectiveStart.secsTo(end) / 60 .." << effectiveStart.secsTo(end) / 60;
 | 
			
		||||
                            qCritical() << "| end .............................." << end.toString(Qt::ISODate) << endl;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -771,7 +331,6 @@ int main() {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        qCritical() << "SUCCESS";
 | 
			
		||||
                    }
 | 
			
		||||
                    qCritical() << "start ............................" << cs.toString();
 | 
			
		||||
                    qCritical() << "start ............................" << start.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << "effectiveStart ..................." << effectiveStart.toString(Qt::ISODate);
 | 
			
		||||
                    qCritical() << "cost ............................." << cost;
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,8 @@ CONFIG(debug, debug|release) {
 | 
			
		||||
 | 
			
		||||
SOURCES += main.cpp
 | 
			
		||||
 | 
			
		||||
# HEADERS +=
 | 
			
		||||
 | 
			
		||||
# HEADERS += \
 | 
			
		||||
 | 
			
		||||
# OTHER_FILES += \
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
#include "terminal_utils.h"
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <endian.h>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
namespace TU {
 | 
			
		||||
    char const *terminalStatus(uint8_t status) {
 | 
			
		||||
        switch (status) {
 | 
			
		||||
        case TERMINAL_CB2_KEYS_NOT_PRESENT:
 | 
			
		||||
            return "CB2 KEYS NOT PRESENT";
 | 
			
		||||
        case TERMINAL_NO_BANKING_PARAMETERS_PRESENT:
 | 
			
		||||
            return "NO BANKING PARAMETERS PRESENT";
 | 
			
		||||
        case TERMINAL_IS_BLOCKED:
 | 
			
		||||
            return "TERMINAL IS BLOCKED";
 | 
			
		||||
        case TERMINAL_NOT_OPERATIVE:
 | 
			
		||||
            return "TERMINAL NOT OPERATIVE";
 | 
			
		||||
        case TERMINAL_IS_READY_AND_ACTIVE:
 | 
			
		||||
            return "TERMINAL IS READY AND ACTIVE";
 | 
			
		||||
        case TERMINAL_IS_READY_AND_NOT_ACTIVE:
 | 
			
		||||
            return "TERMINAL IS READY AND *NOT* ACTIVE";
 | 
			
		||||
        case TERMINAL_LOG_FULL:
 | 
			
		||||
            return "TERMINAL LOG IS FULL";
 | 
			
		||||
        default:
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QByteArray int2Hex(int i) {
 | 
			
		||||
        return QByteArray::fromHex(
 | 
			
		||||
                QString().setNum(i, 16).toLocal8Bit().constData()).toHex();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint16_t getNextTransactionId() {
 | 
			
		||||
        static std::atomic<int> i{0};
 | 
			
		||||
        int j = 0;
 | 
			
		||||
 | 
			
		||||
        while ((j = (++i % 100)) == 0); // 1 <= j <= 99
 | 
			
		||||
 | 
			
		||||
        return htobe16(((j / 10) + 0x30) << 8) | ((j % 10) + 0x30);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t crc32(uint32_t crc, unsigned char* pData, size_t len) {
 | 
			
		||||
 | 
			
		||||
        qCritical() << "updateCRC" << QByteArray((char *)pData, len).toHex();
 | 
			
		||||
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        int j = 0;
 | 
			
		||||
        unsigned char ucCarry = 0x00;
 | 
			
		||||
 | 
			
		||||
        crc = ~crc;
 | 
			
		||||
        while (len > 0) {
 | 
			
		||||
            uint32_t const c = pData[i];
 | 
			
		||||
            crc ^= c;
 | 
			
		||||
            ++i;
 | 
			
		||||
 | 
			
		||||
            for (j = 0; j < 8; ++j) {
 | 
			
		||||
                ucCarry = crc & 1;
 | 
			
		||||
                crc >>= 1;
 | 
			
		||||
 | 
			
		||||
                if (ucCarry) {
 | 
			
		||||
                    crc ^= 0xedb88320;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            --len;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ~crc;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t crc32(QByteArray const &ba) {
 | 
			
		||||
        uint32_t crc = 0;
 | 
			
		||||
        return crc32(crc, (uint8_t *)ba.data(), ba.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char lrc(QByteArray const &ba) {
 | 
			
		||||
        char crc = 0;
 | 
			
		||||
        for (int i = 0; i < ba.size(); ++i) {
 | 
			
		||||
            crc ^= ba[i];
 | 
			
		||||
        }
 | 
			
		||||
        return crc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isBigEndian() {
 | 
			
		||||
        union {
 | 
			
		||||
            uint32_t i;
 | 
			
		||||
            char c[4];
 | 
			
		||||
        } bint = {0x01020304};
 | 
			
		||||
 | 
			
		||||
        return bint.c[0] == 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#ifndef TERMINAL_UTILS_H_INCLUDED
 | 
			
		||||
#define TERMINAL_UTILS_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <cinttypes>
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
 | 
			
		||||
namespace TU {
 | 
			
		||||
 | 
			
		||||
    enum STATUS : uint8_t {
 | 
			
		||||
        TERMINAL_CB2_KEYS_NOT_PRESENT = 0x30,
 | 
			
		||||
        TERMINAL_NO_BANKING_PARAMETERS_PRESENT = 0x31,
 | 
			
		||||
        TERMINAL_IS_BLOCKED = 0x32,
 | 
			
		||||
        TERMINAL_NOT_OPERATIVE = 0x33,
 | 
			
		||||
        TERMINAL_IS_READY_AND_ACTIVE = 0x34,
 | 
			
		||||
        TERMINAL_IS_READY_AND_NOT_ACTIVE = 0x35,
 | 
			
		||||
        TERMINAL_LOG_FULL = 0x36
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    char const *terminalStatus(uint8_t status);
 | 
			
		||||
    QByteArray int2Hex(int i);
 | 
			
		||||
    uint16_t getNextTransactionId();
 | 
			
		||||
 | 
			
		||||
    //uint32_t crc32(const char *s, size_t n);
 | 
			
		||||
    //uint32_t crc32(QByteArray const &ba);
 | 
			
		||||
    uint32_t crc32(QByteArray const &ba);
 | 
			
		||||
    uint32_t crc32(uint32_t crc, unsigned char* pData, size_t len);
 | 
			
		||||
 | 
			
		||||
    char lrc(QByteArray const &ba);
 | 
			
		||||
    bool isBigEndian();
 | 
			
		||||
}
 | 
			
		||||
#endif // TERMINAL_UTILS_H_INCLUDED
 | 
			
		||||
		Reference in New Issue
	
	Block a user