MOBILISIS-Calculator/main/cc_iuc_asynchpos.cpp
2024-06-13 17:23:47 +02:00

2132 lines
66 KiB
C++
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* cc_iuc_asynchpos.c
*
* Created: 21.11.2017 16:36:28
* Author: Matthias
*/
#include "cc_iuc_asynchpos.h"
#include "aes128.h"
#include <QByteArray>
#include <QDebug>
//#include <log.h>
uint32_t iuc_asynchpos_sub_updateCRC(uint32_t crc, char* pData, size_t len) {
// berechne CRC32 nach Polynom x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
QByteArray a(pData, len);
qCritical() << "updateCRC" << a.toHex(' ');
qCritical() << "updateCRC" << len;
int i = 0;
int j = 0;
// unsigned long rem;
// unsigned char octet;
// UCHAR *p, *q;
unsigned char ucCarry = 0x00;
crc = ~crc;
while (len > 0) {
crc ^= (uint32_t) pData[i];
++i;
for (j = 0; j < 8; ++j) {
ucCarry = crc & 1;
crc >>= 1;
if (ucCarry) {
crc ^= IUC_ASYNCHPOS_POLYNOME;
}
}
--len;
}
return ~crc;
}
#if 0
#include <buf.h>
extern struct T_CONF eeprom Conf;
extern struct T_dynamicData GWglobTime;
extern struct T_vend Vend;
static struct billAsynchData asynchBill;
extern struct T_GWstate GWstate;
//extern UCHAR GWstate.VendRequest;
unsigned static char messageData[IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE];
ULONG com_totalSecSince1jan2017(void)
{
// eine Zahl erzeugen die sich jede sec ändert und nicht 2x vorkommen darf
// Zeit und Datum in Sekunden umrechnen. Beginne bei 1.1.2017 um 0:00Uhr
// die nächsten Schaltjahre: 2020, 2024, 2028...
// Der Wert wird sich in den nächsten 130 Jahren nicht gleichen/wiederholen
UINT uitmp;
ULONG ultmp;
//uitmp=com_totalDaysSince1Jan2017(GlobTime.Year, GlobTime.Month, GlobTime.Day);
uitmp= ((UINT)GWglobTime.dayOfMon) + ((UINT)GWglobTime.month) * 30;
ultmp=(ULONG)uitmp;
ultmp*=1440L; // Tage--->min
ultmp+=(ULONG) (GWglobTime.MinOfDay);//GlobTime.MinOfDay; // min von heute drauf
ultmp*=60L;
return ultmp;
}
void generate_UniqueTransNr(UCHAR *buf)
{
// buf>=20 bytes!
UCHAR tmp12[12];
ULONG ultmp = 0;
ULONG transID = com_totalSecSince1jan2017();
// a) Transaction ID, max 19 chars
// ab April 2017: TID muss über alle Automaten und über alle Zeiten eindeutig sein,
// sonst gibt SessionBase keine Antwort.
//uitmp=VKdata.TransID; sub_BufferNummEntry(ultmp); // einfache Version bis März 2017
biox_ClearMem(buf, '0', 19);
biox_ClearMem(tmp12, 0, 12);
//VdKdata.TransID = com_totalSecSince1jan2017();
//biox_ultoa(VKdata.TransID, tmp12);
biox_ultoa(transID, tmp12);
biox_MemCpPos(tmp12, buf, 1);
// Automaten-nr auch rein, sonst können versch. Automaten die gleiche Nummer haben!
biox_ClearMem(tmp12, 0, 12);
ultmp=(ULONG) Conf.MachNr; //.MachineID;
biox_ultoa(ultmp, tmp12);
biox_MemCpPos(tmp12, buf, 11);
biox_ClearMem(tmp12, 0, 12);
ultmp=(ULONG)Conf.CustomNr; //.CustID;
biox_ultoa(ultmp, tmp12);
biox_MemCpPos(tmp12, buf, 16);
buf[19]=0;
}
void iuc_asynchpos_sub_initArray(unsigned char* pArray, int length) {
unsigned int uitemp = 0;
for (uitemp = 0; uitemp < length; ++uitemp)
pArray[uitemp] = 0x00;
}
void iuc_asynchpos_setTerminalID(unsigned char *pID, unsigned int length) {
unsigned int uctemp = 0;
if (!biox_StrComp(pID,terminalID,length)) {
for (uctemp = 0; uctemp < length; ++uctemp) {
terminalID[uctemp] = pID[uctemp];
}
}
}
void iuc_asynchpos_setTerminalAPAK(unsigned char *pAPAK, unsigned int length) {
unsigned char uctemp = 0;
if (!biox_StrComp(pAPAK,terminalAPAK,length)) {
for (uctemp = 0; uctemp < length; ++uctemp) {
terminalAPAK[uctemp] = pAPAK[uctemp];
Conf.APAK_backup[uctemp] = pAPAK[uctemp];
}
}
}
ULONG iuc_asynchpos_sub_updateCRC(ULONG crc, UCHAR* pData, UINT len) //TODO
{
// berechne CRC32 nach Polynom x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
int i = 0;
int j = 0;
// unsigned long rem;
// unsigned char octet;
// UCHAR *p, *q;
unsigned char ucCarry = 0x00;
crc = ~crc;
while (len > 0) {
crc ^= (ULONG) pData[i];
++i;
for (j = 0; j < 8; ++j) {
ucCarry = crc & 1;
crc >>= 1;
if (ucCarry) {
crc ^= IUC_ASYNCHPOS_POLYNOME;
}
}
--len;
}
return ~crc;
}
unsigned char iuc_asynchpos_rts() {
unsigned char timeOut = 0x00;
unsigned char uctmp = 0x00;
brd_switch_RS3(RS3SW2IUC);
biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none);
uctmp = EOT;
biox_Usart3_ClearRecBuffer();
biox_Usart3_SendBlock(&uctmp,1);
while (timeOut < 0x06 && uctmp != ENQ) {
biox_delay_ms(400);
if (biox_Usart3_NewTelegram()) {
brd_SendDiagStr("->IUC ASYNCHPOS 0x05 (ENQ) received. RTS.",1);
biox_Usart3_GetRecBuffer(&uctmp,1);
biox_Usart3_ClearRecBuffer();
iucAsynchpoxDataContext = 0x00;
} else {
brd_SendDiagStr("->IUC ASYNCHPOS waiting for 0x05 (ENQ).",1);
biox_Usart3_ClearRecBuffer();
biox_Usart3_SendBlock(&uctmp,1);
}
++timeOut;
}
if (uctmp == ENQ)
return 0;
return 1;
}
unsigned char iuc_asynchpos_cts() {
unsigned int recLength;
unsigned char uctmp = ENQ;
recLength = biox_Usart3BuffSize();
if (recLength > 0) {
biox_Usart3_GetRecBuffer(&uctmp,1);
if (uctmp == EOT) { //The terminal is trying to send us data
uctmp = ENQ;
biox_Usart3_ClearRecBuffer();
biox_Usart3_SendBlock(&uctmp,1);
biox_delay_ms(10);
return 1;
}
}
return 0;
}
unsigned char iuc_asynchpos_waitforACK() {
//unsigned char timeOut = 0x00;
unsigned char retVal = 0x00;
unsigned char rxData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
unsigned int uitmp = 0;
uitmp = biox_Usart3BuffSize();
if (uitmp > 1) {
//iuc_asynchpos_sub_initArray(rxData_,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
biox_Usart3_GetRecBuffer(rxData_,uitmp);
if (GWstate.DebugLevel & 0x10)
{
brd_SendDiagStr("->IUC ASYNCHPOS (ACK/NACK) rx data: ",0);
brd_SendDiagBlock(rxData_,1,uitmp);
}
retVal = rxData_[0];
for (;uitmp > 0;--uitmp) {
if (rxData_[uitmp] == 0x0A) {
retVal |= 0xA0;
}
if (rxData_[uitmp] == 0x0F) {
retVal |= 0xF0;
}
}
} else {
//if (uitmp == 1)
biox_Usart3_GetRecBuffer(&retVal,1);
}
biox_Usart3_ClearRecBuffer();
return retVal;
}
unsigned char iuc_asynchpos_send_serial(unsigned char* pData, unsigned int length, unsigned char needRTS, unsigned char overrideACK) {
unsigned int uitmp = 0;
unsigned int uitmp2 = 0;
unsigned int uitmp3 = 0;
unsigned int txCounter = 0;
unsigned int dxCounter = 0;
unsigned char uctmp = 0x00;
// unsigned char uctmp2 =0x00;
unsigned char chksum = 0x00;
//unsigned char dataContext = 0x00;
unsigned int retryCount = 0;
unsigned long lastRetry = 0;
unsigned int dxLength;
// unsigned int dx = biox_StrLen(pData) + 1;
unsigned char rxBuf[8];
//unsigned char pData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
// unsigned int loopCount = 1000;
// unsigned char retVal = 0x01;
//preparing to send
if (needRTS) {
brd_SendDiagStr("->IUC ASYNCHPOS sending 0x04 (EOT).",1);
uctmp = iuc_asynchpos_rts();
}
//sending data
if (!uctmp) {
brd_SendDiagStr("----->IUC ASYNCHPOS",1);
iuc_asynchpos_sub_initArray(txAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
//iuc_asynchpos_sub_initArray(pData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
//biox_CopyBlock(pData,0,pData_,0,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
/*dxCounter = 0;
for (uitmp = 0; uitmp < dx + dxCounter; ++uitmp) {
if ((pData[uitmp] >= STX && pData[uitmp] <= ACK2)
|| (pData[uitmp] == DLE) || (pData[uitmp] == NAK)) {
pData[uitmp] = (pData[uitmp] + 0x30);
for (uitmp2 = uitmp; uitmp2 < dx + dxCounter; ++uitmp2) {
pData[uitmp2 + 1] = pData[uitmp2];
}
pData[uitmp] = DLE;
++dxCounter;
}
}
dxCounter = 0;*/
for (uitmp = 0; uitmp < length; uitmp += IUC_ASYNCHPOS_MIN_PACKET_SIZE) {
//if (dxCounter > 0)
//uitmp -= dxCounter;
uctmp = 0x00;
dxCounter = 0;
chksum = 0x00;
dxLength = IUC_ASYNCHPOS_MIN_PACKET_SIZE;
if (length - uitmp <= IUC_ASYNCHPOS_MIN_PACKET_SIZE)
dxLength = 2 + length - uitmp;
iuc_asynchpos_sub_initArray(txAsynchData, 3 + IUC_ASYNCHPOS_MIN_PACKET_SIZE);
//Packet structure is STX <packet_data> ETX1|ETX2 {LRC}
txAsynchData[0] = STX;
for (txCounter = 0; (txCounter/* + dxCounter*/) < dxLength; ++txCounter) {
//for (txCounter = 0; txCounter < dxLength; ++txCounter) {
/*if ((pData[uitmp + txCounter] >= STX && pData[uitmp + txCounter] <= ACK2)
|| (pData[uitmp + txCounter] == DLE) || (pData[uitmp + txCounter] == NAK)) {
txAsynchData[1 + txCounter + dxCounter] = DLE;
uctmp = (pData[uitmp + txCounter] + 0x30);
++dxCounter;
txAsynchData[1 + txCounter + dxCounter] = uctmp; //(pData[uitmp + txCounter] + 0x30);
} else {*/
txAsynchData[1 + txCounter/* + dxCounter*/] = pData[uitmp + txCounter];
if ((pData[uitmp + txCounter] >= STX && pData[uitmp + txCounter] <= ACK2)
|| (pData[uitmp + txCounter] == DLE) || (pData[uitmp + txCounter] == NAK)) {
++dxCounter;
}
}
for (uitmp2 = 1; uitmp2 < dxLength + dxCounter; ++uitmp2) {
if ((txAsynchData[uitmp2] >= STX && txAsynchData[uitmp2] <= ACK2)
|| (txAsynchData[uitmp2] == DLE) || (txAsynchData[uitmp2] == NAK)) {
for (uitmp3 = dxLength + dxCounter; uitmp3 > uitmp2; --uitmp3) {
txAsynchData[uitmp3] = txAsynchData[uitmp3 - 1];
}
txAsynchData[uitmp2 + 1] = (txAsynchData[uitmp2 + 1] + 0x30);
txAsynchData[uitmp2] = DLE;
}
}
/*if (dxLength < IUC_ASYNCHPOS_MIN_PACKET_SIZE && txAsynchData[txCounter + dxCounter] != 0x00) {
++dxCounter;
}*/
for (uitmp2 = 1; uitmp2 <= (txCounter + dxCounter); ++uitmp2) {
chksum ^= txAsynchData[uitmp2];
}
if (!iucAsynchpoxDataContext) {
txAsynchData[1 + txCounter + dxCounter] = ETX1;
chksum ^= ETX1;
} else {
txAsynchData[1 + txCounter + dxCounter] = ETX2;
chksum ^= ETX2;
}
txAsynchData[2 + txCounter + dxCounter] = chksum;
//Check if the terminal has decided, that our gateway is gone and is frantically sending us EOTs all the time
//iuc_asynchpos_cts();
//send packet
biox_Usart3_ClearRecBuffer();
biox_Usart3_SendBlock(txAsynchData,3 + txCounter + dxCounter);
biox_delay_ms(1);
iuc_asynchpos_sub_initArray(rxBuf,8);
biox_itoa(3 + txCounter + dxCounter,rxBuf);
if (GWstate.DebugLevel & 0x10)
{
brd_SendDiagStr("->IUC ASYNCHPOS Packetlength: ",0);
brd_SendDiagBlock(rxBuf,1,8);
brd_SendDiagStr("->IUC ASYNCHPOS send package: ",0);
brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter);
}
//brd_SendDiagStr("->IUC ASYNCHPOS Send: ",0);
//brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter);
//wait for ACK
uctmp = 0x00;
lastRetry = 0;
retryCount = 0;
brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1);
do {
uctmp = iuc_asynchpos_waitforACK();
//uctmp2 = uctmp;
uctmp &= 0x0F;
//if (!(lastRetry % 10)) {
//}
if ((uctmp == NAK) || ((lastRetry >= 100) && (uctmp == 0x00))) {
brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1);
if (uctmp == NAK)
brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1);
biox_Usart3_SendBlock(txAsynchData,3 + txCounter + dxCounter);
biox_delay_ms(1);
++retryCount;
uctmp = 0x00;
lastRetry = 0;
} else {
++lastRetry;
biox_delay_ms(1);
}
} while (retryCount < 25 && uctmp == 0x00); //Entweder Timeout, keine neuen Versuche oder ein ACK1/ACK2 holen uns hier raus
/*while (retryCount < 5 && (uctmp == 0x00 || uctmp == NAK)) {
uctmp = iuc_asynchpos_waitforACK();
++lastRetry;
// if (uitmp == 0)
// biox_delay_ms(100);
if ((uctmp == NAK) || (uctmp == 0x00 && (lastRetry % 10 == 0x00))) {
biox_Usart2_ClearRecBuffer();
brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1);
biox_Usart2_SendBlock(txAsynchData,3 + txCounter + dxCounter);
biox_delay_ms(10);
brd_SendDiagStr("->IUC ASYNCHPOS resend: ",0);
brd_SendDiagBlock(txAsynchData,1,3 + txCounter + dxCounter);
++retryCount;
} else if (uctmp == ETX1 || uctmp == ETX2) {
biox_Usart2_ClearRecBuffer();
uctmp = NAK;
biox_Usart2_SendBlock(&uctmp,1);
}
}*/
if (!uctmp) {
brd_SendDiagStr("->IUC ASYNCHPOS Terminal did not reply.",1);
return 1; //sending failed
}
//iuc_asynchpos_sub_initArray(txAsynchData, 3 + txCounter + dxCounter);
if (uctmp == ACK1) {
brd_SendDiagStr("->IUC ASYNCHPOS ACK 1 (serial)",1);
//dataContext = 0x01;
iucAsynchpoxDataContext = 0x01;
}
if (uctmp == ACK2) {
brd_SendDiagStr("->IUC ASYNCHPOS ACK 2 (serial)",1);
//dataContext = 0x00;
iucAsynchpoxDataContext = 0x00;
}
if (retryCount >= 5) {
brd_SendDiagStr("->IUC ASYNCHPOS Too much NACKs, giving up.",1);
return 2; //too much NACKs, giving up
}
}
/*uctmp2 &= 0xF0;
if (uctmp2 == 0xA0) {
retVal = 1;
}
if (uctmp2 == 0xF0) {
retVal = 0;
}*/
/*if (!overrideACK) {
brd_SendDiagStr("->IUC ASYNCHPOS Retrieving.",1);
retVal = 0x01;
uitmp = 0x01;
while(uitmp > 0 && loopCount > 0) {
uitmp = iuc_asynchpos_recieve_serial(0x01);
biox_delay_ms(1);
--loopCount;
biox_Usart2_ClearRecBuffer();
}
if (loopCount == 0) {
brd_SendDiagStr("->IUC ASYNCHPOS Retrieving timeout!",1);
retVal = 0x00;
}
brd_SendDiagStr("->IUC ASYNCHPOS Retrieving ended.",1);
}*/
return 1;//retVal;//(UCHAR) uitmp;
} else {
brd_SendDiagStr("->IUC ASYNCHPOS Not ready to send to POS, giving up.",1);
}
return 2;
}
unsigned int iuc_asynchpos_send(unsigned char packetType, unsigned char* pData, unsigned int length, unsigned char needRTS) {
unsigned char txData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
unsigned char tempID [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE];
unsigned char tempID_ [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE];
unsigned char tempAPAK [IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE];
unsigned long uitmp = 0;
unsigned int posID = 0;
unsigned long chksum = 0;
unsigned int messageLength = length + 1;
unsigned int length_ = length + 1;
unsigned char pData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
unsigned char uctemp = 0;
// unsigned char retries = 4;
unsigned char rxBuf[8];
iuc_asynchpos_crc_old = 0;
iuc_asynchpos_sub_initArray(rxBuf, 8);
iuc_asynchpos_sub_initArray(pData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
biox_CopyBlock(pData,0,pData_,0,length_);
iuc_asynchpos_sub_initArray(txData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
iuc_asynchpos_sub_initArray(tempID, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE);
iuc_asynchpos_sub_initArray(tempID_, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE);
iuc_asynchpos_sub_initArray(tempAPAK, IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE);
//header
/*
The header of the message is composed of:
? 1 byte packet Type, which indicates the type of the packet;
? 8 bytes Packet ID, a unique ID to achieve maximum security (for information on forming
Packet ID see chapter 3.4 Communication security);
? 1 byte P.O.S. ID length;
? ASCII encoded P.O.S. ID (up to 255 bytes); ((gemeint ist Terminal ID)
*/
txData_[2] = packetType;
//1 byte P.O.S. ID length
/*for (uitmp = 0; uitmp < 32 && terminalID[uitmp] != 0x00; ++uitmp) {
++posID; // -= uitmp;
}*/
posID = biox_StrLen(terminalID)/* + 1*/;
//++posID;
txData_[11] = (UCHAR) posID;
messageLength += (10 + posID); //Added header
txData_[0] = (messageLength) & 0xFF00; //high byte
txData_[1] = (messageLength) & 0x00FF; //low byte
//8 byte Packet ID
/*
Apak: 9D547268976ADE1BBB39DE90F3A449E5
Terminal id: T-LT-OPT-01
*/
//calculate CRC32
uctemp = (UCHAR) posID;
chksum = IUC_ASYNCHPOS_POLYNOME_INITIAL;
chksum = iuc_asynchpos_sub_updateCRC(chksum,&uctemp,1);
chksum = iuc_asynchpos_sub_updateCRC(chksum,terminalID,posID);
//for (uitmp = 0; uitmp < length_; ++uitmp) {
chksum = iuc_asynchpos_sub_updateCRC(chksum,pData_/*[uitmp]*/,length_);
//}
//XOR crc value with APAK
//chksum = 2502456899; //HACK FOR TESTING, REMOVE LATER!
for(uitmp = 0; uitmp < IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE; ++uitmp) {
tempAPAK[uitmp] |= biox_ah2ui_char(terminalAPAK[uitmp * 2]) << 4;
tempAPAK[uitmp] |= biox_ah2ui_char(terminalAPAK[(uitmp * 2) + 1]);
//tempAPAK[uitmp] = (terminalAPAK[uitmp * 2] << 8) | (terminalAPAK[(uitmp * 2) + 1]);
}
tempID[0] = (chksum >> 24) & 0xFF;
tempID[1] = (chksum >> 16) & 0xFF;
tempID[2] = (chksum >> 8) & 0xFF;
tempID[3] = chksum & 0xFF;
for (uitmp = 0; uitmp < 4; ++uitmp) {
tempID[uitmp] ^= tempAPAK[uitmp]; //terminalAPAK[uitmp];
}
for (uitmp = 4; uitmp < IUC_ASYNCHPOS_MIN_BASE_BYTE_DATA_SIZE; ++uitmp) {
tempID[uitmp] = tempAPAK[uitmp]; //terminalAPAK[uitmp];
}
//Eyncrypt result with APAK, according to AES128
aes_encrypt(tempID,tempID_,tempAPAK);
//get the leftmost 8 byte of that value and set then as Packet ID
for (uitmp = 0; uitmp < 8; ++uitmp)
txData_[3 + uitmp] = tempID_[uitmp];
//P.O.S.ID
for (uitmp = 0; uitmp < posID; ++uitmp) {
txData_[12 + uitmp] = terminalID[uitmp];
}
//Message
//1 byte - marker
//0 . 7F bytes - tag name
//2 + N bytes - data
for (uitmp = 0; uitmp < length_; ++uitmp) {
txData_[12 + posID + uitmp] = pData_[uitmp];
}
brd_SendDiagStr("->IUC ASYNCHPOS send message: ",0);
brd_SendDiagBlock(txData_,1,messageLength);
//Message compiled, now send it via serial
uitmp = 1;
//while (retries > 0 && uitmp > 0) {
//uitmp = iuc_asynchpos_send_serial(txData_, (messageLength + 1));
//--retries;
if (iuc_asynchpos_send_serial(txData_, (messageLength/* + 1*/),needRTS,0x00)) {
//brd_SendDiagStr("->IUC ASYNCHPOS Message failed!",1);
//TODO Message sending failed -> Error handling here
//return 1;
uitmp = 0x00;
brd_SendDiagStr("->IUC ASYNCHPOS Message NOT send",1);
} else {
brd_SendDiagStr("->IUC ASYNCHPOS Message send",1);
} /*else {
--retries;
}
}*/
//if (!uitmp)
//return 1;
/*if (retries == 0) {
brd_SendDiagStr("->IUC ASYNCHPOS Message failed!",1);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0xFF;
vmc_SendWithBuffer(rxBuf,20,0x69,0);
return 1;
}
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0x00;
vmc_SendWithBuffer(rxBuf,20,0x69,0);*/
//brd_SendDiagStr("->IUC ASYNCHPOS Message send",1);
//while(iuc_asynchpos_recieve_serial());
return 0;
}
/*
Let us assume that a client wants to purchase items and he wants to pay for these items with his
bank card. When the client is ready to authorize the transaction, the ECR needs to send [Authorize]
request for the operations to start. Within the request, the ECR must include:
? An [Amount] sub tag with the tender amount in minor currency;
? A [Currency] sub tag with a three digit currency code;
? A [DocNr] sub tag with the number referencing the current receipt;
? [Time] – the time of the transaction;
? A [Lang] sub tag specifying a language code;
As a result, the P.O.S. will reply by an [AuthorizationResult] device event with an [ID], [DocNr],
[Result] sub tags. When ECR closes/finalizes its receipt, ECR must send [DocClosed] event to
finalize bank operation of in this receipt. A successful authorization Id from [AuthorizationResult]
must be included in [DocClosed] message. Only Id of successful authorization has to be included,
other Ids has to be omitted from message.
Depending on the configuration, and requirements, the ECR may receive a [PrintReceipt] event
(though some models of P.O.S. could as well print the receipt itself), with an [ID], [DocNr], and the
[ReceiptText], to be printed out. The [PrintReceipt] event may occur at any time of the operation,
whenever the P.O.S. needs to print something, and it should be printed as soon as possible. ECR
may be occupied during the event, so it may start printing when no more operations are waiting to
be processed. After the receipt has been printed, the ECR has to send a [PrintResult] to P.O.S. to
confirm the successful action. P.O.S. may send [GetMessageBoxInput] message to ECR if signature
of Client needed. ECR must send [InputResult] message to POS. This message informs about sign
status.
During bank card authorization [PrintReceipt] messages usually are sent before
[AuthorizationResult] event.
POS could send additional [DisplayText] message(s) to ECR to inform about process steps.
*/
void iuc_asynchpos_sub_initZero(unsigned char* pArray, int length) {
unsigned int uitemp = 0;
for (uitemp = 0; uitemp < (length - 1); ++uitemp)
pArray[uitemp] = 0x30;
pArray[length - 1] = 0x00;
}
void iuc_asynchpos_sub_clear_message(unsigned char fillwithZero) {
if (fillwithZero) {
iuc_asynchpos_sub_initZero(asynchBill.id,37);
iuc_asynchpos_sub_initZero(asynchBill.docNr,33);
/*iuc_asynchpos_sub_initZero(asynchBill.token,25);
iuc_asynchpos_sub_initZero(asynchBill.result,8);
iuc_asynchpos_sub_initZero(asynchBill.amount,10);
iuc_asynchpos_sub_initZero(asynchBill.authCode,7);
iuc_asynchpos_sub_initZero(asynchBill.rrn,13);
iuc_asynchpos_sub_initZero(asynchBill.stan,7);
iuc_asynchpos_sub_initZero(asynchBill.cardtype,33);*/
//iuc_asynchpos_sub_initZero(asynchBill.errCode,17);
} else {
iuc_asynchpos_sub_initArray(asynchBill.id,37);
iuc_asynchpos_sub_initArray(asynchBill.docNr,33);
/*iuc_asynchpos_sub_initArray(asynchBill.token,25);
iuc_asynchpos_sub_initArray(asynchBill.result,8);
iuc_asynchpos_sub_initArray(asynchBill.amount,10);
iuc_asynchpos_sub_initArray(asynchBill.authCode,7);
iuc_asynchpos_sub_initArray(asynchBill.rrn,13);
iuc_asynchpos_sub_initArray(asynchBill.stan,7);
iuc_asynchpos_sub_initArray(asynchBill.cardtype,33);*/
//iuc_asynchpos_sub_initArray(asynchBill.errCode,17);
}
}
void iuc_asynchpos_sub_sendACK(unsigned char switchPrint) {
unsigned char messageReturnData[100];
unsigned int uitemp = 0;
unsigned int uitemp2 = 0;
unsigned int uitemp3 = 0;
unsigned char uctmp = 0;
unsigned int lastRetry = 0;
unsigned int retryCount = 0;
iuc_asynchpos_sub_initArray(messageReturnData, 100); //iuc_asynchpos_sub_initArray(messageData, messageLength + 1);//iuc_asynchpos_sub_initArray(messageReturnData, IUC_ASYNCHPOS_MAX_MESSAGE_SIZE);
switch (switchPrint) {
case 1:
for (uitemp = 0; uitemp < 8; ++uitemp) {
messageReturnData[uitemp + 3] = terminalSignature[uitemp];
}
messageReturnData[uitemp + 3] = (UCHAR) biox_StrLen(terminalID);
for (uitemp = 0; uitemp < biox_StrLen(terminalID); ++uitemp) {
messageReturnData[uitemp + 12] = terminalID[uitemp];
}
uitemp += 10;
break;
case 2:
for (uitemp = 0; uitemp < 8; ++uitemp) {
messageReturnData[uitemp + 3] = terminalSignature[uitemp + 8];
}
messageReturnData[uitemp + 3] = biox_StrLen(terminalID);
for (uitemp = 0; uitemp < biox_StrLen(terminalID); ++uitemp) {
messageReturnData[uitemp + 12] = terminalID[uitemp];
}
uitemp += 10;
break;
case 0:
default:
for (uitemp = 0; uitemp < rxAsynchData[11] + 9; ++uitemp) {
messageReturnData[uitemp + 3] = rxAsynchData[uitemp + 3];
}
++uitemp;
break;
}
messageReturnData[0] = uitemp & (0xFF00);
messageReturnData[1] = uitemp & (0x00FF);
messageReturnData[2] = 0x0A;
//iuc_asynchpos_send_serial(messageReturnData,uitemp/* + 1*/,0x00,0x01);
for (uitemp2 = uitemp + 2; uitemp2 > 0; --uitemp2) {
messageReturnData[uitemp2] = messageReturnData[uitemp2 - 1];
}
uitemp += 2;
messageReturnData[0] = 0x01;
//convert characters
for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) {
if ((messageReturnData[uitemp2] >= STX && messageReturnData[uitemp2] <= ACK2)
|| (messageReturnData[uitemp2] == DLE) || (messageReturnData[uitemp2] == NAK)) {
++uitemp;
for (uitemp3 = uitemp + 1; uitemp3 > uitemp2; --uitemp3) {
messageReturnData[uitemp3] = messageReturnData[uitemp3 - 1];
}
messageReturnData[uitemp2 + 1] = messageReturnData[uitemp2 + 1] + 0x30;
messageReturnData[uitemp2] = DLE;
}
}
messageReturnData[uitemp + 1] = ETX1;
//calculate chksum
for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) {
messageReturnData[uitemp + 2] ^= messageReturnData[uitemp2];
}
biox_Usart3_SendBlock(messageReturnData,uitemp2+1);
//wait for ACK
uctmp = 0x00;
lastRetry = 1;
retryCount = 0;
brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1);
do {
uctmp = iuc_asynchpos_waitforACK();
//if (!(lastRetry % 10)) {
//}
if (uctmp == NAK || ((lastRetry % 500 == 0) && (uctmp == 0x00))) {
brd_SendDiagStr("->IUC ASYNCHPOS waiting for answer (serial)",1);
if (uctmp == NAK)
brd_SendDiagStr("->IUC ASYNCHPOS NACK (serial)",1);
biox_Usart3_SendBlock(messageReturnData,uitemp2+1);
biox_delay_ms(1);
++retryCount;
uctmp = 0x00;
lastRetry = 1;
} else {
++lastRetry;
biox_delay_ms(1);
}
} while (retryCount < 5 && uctmp == 0x00); //Entweder Timeout, keine neuen Versuche oder ein ACK1/ACK2 holen uns hier raus
if (!uctmp) {
brd_SendDiagStr("->IUC ASYNCHPOS Terminal did not reply.",1);
//return 1; //sending failed
}
if (uctmp == ACK1) {
brd_SendDiagStr("->IUC ASYNCHPOS ACK 1 (ACK serial)",1);
//dataContext = 0x01;
iucAsynchpoxDataContext = 0x01;
}
if (uctmp == ACK2) {
brd_SendDiagStr("->IUC ASYNCHPOS ACK 2 (ACK serial)",1);
//dataContext = 0x00;
iucAsynchpoxDataContext = 0x00;
}
if (retryCount >= 5) {
brd_SendDiagStr("->IUC ASYNCHPOS (ACK serial) Too much NACKs, giving up.",1);
//return 2; //too much NACKs, giving up
}
}
void iuc_asynchpos_resetBuffers(unsigned char sendENQ) {
unsigned char uctmp = ENQ;
unsigned char rxBuf[8];
if (sendENQ != 0x02) {
rxCounter = 0;
messageLength = 0;
iuc_asynchpos_sub_initArray(rxAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
iuc_asynchpos_sub_initArray(txAsynchData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
}
if (sendENQ) {
iucAsynchpoxDataContext = 0x00;
ENQrecieved = 1;
brd_SendDiagStr("->IUC ASYNCHPOS 0x04 (EOT) received.",1);
brd_switch_RS3(RS3SW2IUC);
biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none);
biox_delay_ms(1);
biox_Usart3_ClearRecBuffer();
brd_SendDiagStr("->IUC ASYNCHPOS send 0x05 (ENQ). CTS",1);
biox_Usart3_SendBlock(&uctmp,1);
if (asynchState <= 0x03)
{
brd_SendDiagStr("->IUC ASYNCHPOS sending an error to the VMC",1);
iuc_asynchpos_sub_initArray(rxBuf,8);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0xFF;
vmc_SendWithBuffer(rxBuf,8,0x69,0);
}
}
}
//46
void iuc_asynchpos_command_print_Result(unsigned char status) { //Finalize sale
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "PrintResult";
UCHAR tagName[] = "DocNr";
UCHAR tag2Name[] = "Result";
UCHAR tag3Name[] = "ID";
UCHAR tag2ValueO[] = "OK";
UCHAR tag2ValueE[] = "ERROR";
unsigned char uctmp = status;
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
uitemp = biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
//ID
message[uitemp] = (UCHAR) biox_StrLen(tag3Name);
++uitemp;
biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name));
uitemp += (1 + biox_StrLen(tag3Name));
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.printId);//value length
++uitemp;
biox_CopyBlock(asynchBill.printId,0,message,uitemp, biox_StrLen(asynchBill.printId));//value
uitemp += biox_StrLen(asynchBill.printId);
//DocNr
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length
++uitemp;
biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value
uitemp += biox_StrLen(asynchBill.docNr);
//Result
message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name
uitemp += (1 + biox_StrLen(tag2Name));
if (!uctmp) {
message[uitemp] = (UCHAR) biox_StrLen(tag2ValueE);//value length
++uitemp;
biox_CopyBlock(tag2ValueE,0,message,uitemp, biox_StrLen(tag2ValueE));//value
uitemp += biox_StrLen(tag2ValueE)/* + 1*/;
} else {
message[uitemp] = (UCHAR) biox_StrLen(tag2ValueO);//value length
++uitemp;
biox_CopyBlock(tag2ValueO,0,message,uitemp, biox_StrLen(tag2ValueO));//value
uitemp += biox_StrLen(tag2ValueO)/* + 1*/;
}
iuc_asynchpos_send(packetType,message,uitemp,0x00);
}
void iuc_asynchpos_handleMessage(unsigned char* pData) {
//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;
}
/*while (pData[uitmp] != 0x00) { //0x00 is the end marker
if (tagNameLength > 0x7F) {
//tagNameLength -= 0x80;
for (uitmp2 = 0; uitmp2 < (tagNameLength - 0x80); ++uitmp2) {
tagName[uitmp2] = pData[uitmp + 1 + uitmp2];
}
//TODO Do something with the name here
uitmp = uitmp2 + 1;
tagNameLength = pData[uitmp];
} else {
for (uitmp2 = 0; uitmp2 < tagNameLength; ++uitmp2) {
tagName[uitmp2] = pData[uitmp + 1 + uitmp2];
}
//TODO Do something with the name here
uitmp = uitmp2 + 1;
curElementLength = ((UINT) pData[uitmp] << 8) | pData[uitmp];
for (uitmp2 = 0; uitmp2 < curElementLength; ++uitmp2) {
curElement[uitmp2] = pData[uitmp + 1 + uitmp2];
}
//TODO Do something with the data here
uitmp = uitmp2 + 1;
tagNameLength = pData[uitmp];
}
}*/
}
void iuc_asynchpos_startCommunication() {
unsigned char uctmp = EOT;
biox_Usart3_ClearRecBuffer();
biox_Usart3_SendBlock(&uctmp,1);
}
void iuc_asynchpos_init() {
//TODO: CHANGE THIS LATER ON! TEST ONLY!
#ifdef IUC_ASYCHNPOS_TESTMODE
unsigned char APAK[] = "9D547268976ADE1BBB39DE90F3A449E5"; //9D547268976ADE1BBB39DE90F3A449E5
unsigned char TID[] = "T-LT-OPT-01";
#endif
unsigned char timeStart[] = "2018-01-01 00:00:00";
unsigned int uitmp = 0;
iuc_asynchpos_sub_initArray(asynchBill.time,20);
biox_CopyBlock(timeStart,0,asynchBill.time,0,biox_StrLen(timeStart));
//iuc_asynchpos_sub_initArray(asynchBill.id,20);
//iuc_asynchpos_sub_initArray(asynchBill.docNr,32);
iuc_asynchpos_sub_clear_message(0x01);
asynchState = 0;
iuc_asynch_keepAlive = 0x00;
iuc_asynch_PrintControl = 0x00;
tableCreated = 0x00;
#ifdef IUC_ASYCHNPOS_TESTMODE
iuc_asynchpos_setTerminalAPAK(APAK, biox_StrLen(APAK));
iuc_asynchpos_setTerminalID(TID, biox_StrLen(TID));
#endif
ENQrecieved = 0x00;
timeInitalized = GWglobTime.SecOfDay;
asynchSessionClosed = 0x00;
iuc_asynch_PRNrecieved = 0x00;
iuc_asynchpos_crc_old = 0;
iucAsynchpoxDataContext = 0x00;
iuc_asynch_printTimeout = IUC_ASYNCHPOS_PRINTTIMOUT;
brd_switch_RS3(RS3SW2IUC);
biox_Usart3_ClearRecBuffer();
biox_Usart3Ini(USART_Mode_Int, USART_Baud19200, USART_data8, USART_stop1, USART_parity_none);
biox_delay_ms(1);
/*
Apak: 9D547268976ADE1BBB39DE90F3A449E5
Terminal id: T-LT-OPT-01
*/
for (uitmp = 0; uitmp < IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE; ++uitmp)
terminalAPAK[uitmp] = Conf.APAK_backup[uitmp];
//biox_CopyBlock(Conf.APAK_backup,0,terminalAPAK,0,IUC_ASYNCHPOS_MIN_BASE_DATA_SIZE);
iuc_asynchpos_resetBuffers(0x00);
iuc_asynchpos_startCommunication();
}
unsigned char iuc_asynchpos_recieve_serial(unsigned char waitforACK) {
unsigned int rxLength = 0;
unsigned int uitemp = 0;
unsigned int uitemp2 = 0;
unsigned char rxData_[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
// unsigned char messageReturnData[100];
unsigned char messageLength_[8];
unsigned char messageCounter_[8];
unsigned char chksum = 0x00;
unsigned char uctmp = 0x00;
unsigned char resetBuffers = 0x00;
//unsigned int rxCounter = messageLength;
unsigned char fullPackage = 0x00;
unsigned char rxBuf[8];
//if (biox_Usart2_NewTelegram()) {
//brd_SendDiagStr("<----- IUC ASYNCHPOS",1);
//get datastream from buffer
//iuc_asynchpos_sub_initArray(rxData_, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
rxLength = biox_Usart3BuffSize();
rxData_[0] = 0xFF;
if (rxLength > 0) {
brd_SendDiagStr("<----- IUC ASYNCHPOS",1);
if (rxLength >= IUC_ASYNCHPOS_MAX_ARRAY_SIZE) {
brd_SendDiagStr("->IUC ASYNCHPOS rx buffer overflow!",1);
biox_Usart3_ClearRecBuffer();
return 8;
}
brd_SendDiagStr("->IUC ASYNCHPOS Data recieved, ISMAS locked!",1);
ism_lock();
timeHoldISMAS = GWglobTime.SecOfDay;
//iuc_asynchpos_sub_initArray(rxData_, rxLength);
biox_Usart3_GetRecBuffer(rxData_,rxLength);
if (GWstate.DebugLevel & 0x10)
{
biox_itoa(rxLength,messageLength_);
brd_SendDiagStr("->IUC ASYNCHPOS recieved: ",0);
brd_SendDiagBlock(messageLength_,1,8);
brd_SendDiagStr("->IUC ASYNCHPOS rx data: ",0);
brd_SendDiagBlock(rxData_,1,rxLength);
if (rxLength <= 1)
brd_SendDiagStr("->IUC ASYNCHPOS Single Byte recieved.",1);
}
for (uitemp = 0; uitemp < rxLength/* && resetBuffers == 0x00*/; ++uitemp) {
if (rxData_[uitemp] == EOT || (!ENQrecieved && rxData_[uitemp] == ENQ)) {//Either we did not initialize everysthing yet OR the PT wants to send something.
if (uitemp == 0 || (uitemp > 0 && (rxData_[uitemp-1] != ETX1 || rxData_[uitemp-1] != ETX2))) {
if (rxData_[uitemp] != ENQ) {
resetBuffers = 0x01;
} else {
resetBuffers = 0x02;
brd_SendDiagStr("->IUC ASYNCHPOS ENQ recieved, ISMAS unlocked!",1);
ism_unlock();
}
}
}
if (rxData_[uitemp] == ETX1 || (rxData_[uitemp] == ETX2))
fullPackage = 0x01;
}
if (resetBuffers) { //Does the terminal want to send? / Did we receive an EOT?
/*ENQrecieved = 0x01;
rxCounter = 0;
messageLength = 0;
iuc_asynchpos_sub_initArray(rxData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);*/
/*if (ENQrecieved == 0) {
brd_SendDiagStr("-> IUC ANSNYCHPOS initialized",1);
} else {
brd_SendDiagStr("->IUC ASYNCHPOS listening to terminal",1);
}*/
if (resetBuffers >= 0x01) {
iuc_asynchpos_resetBuffers(0x01);
} else {
iuc_asynchpos_resetBuffers(0x00);
}
if (rxLength > 1) {
//biox_Usart2_ClearRecBuffer();
uctmp = NAK;
biox_Usart3_SendBlock(&uctmp,1);
}
//iuc_asynchpos_sub_initArray(messageData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
return 2; //Yes, it does. / Yes, we did.
} else
if (ENQrecieved && fullPackage/* && biox_Usart2_NewTelegram()*/) {
brd_SendDiagStr("->IUC ASYNCHPOS Full packet recieved, ISMAS unlocked!",1);
ism_unlock();
//brd_SendDiagStr("->IUC ASYNCHPOS Data recieved.",1);
//calculate chksum
for (uitemp = 1; uitemp < (rxLength - 1) && (rxData_[uitemp - 1] != ACK1 || rxData_[uitemp - 1] != ACK2); ++uitemp) {
chksum ^= rxData_[uitemp];
}
if (chksum != rxData_[uitemp]) {
biox_Usart3_ClearRecBuffer();
uctmp = NAK;
biox_Usart3_SendBlock(&uctmp,1);
brd_SendDiagStr("->IUC ASYNCHPOS Sending NACK (Checksum mismatch).",1);
return 3; //checksum mismatch
} else {
biox_Usart3_ClearRecBuffer();
if (rxData_[rxLength - 2] == ETX1) {
uctmp = ACK1;
biox_Usart3_SendBlock(&uctmp,1);
brd_SendDiagStr("->IUC ASYNCHPOS Sending ACK1.",1);
//iucAsynchpoxDataContext = 0x01;
} else if (rxData_[rxLength - 2] == ETX2) {
uctmp = ACK2;
biox_Usart3_SendBlock(&uctmp,1);
brd_SendDiagStr("->IUC ASYNCHPOS Sending ACK2.",1);
//iucAsynchpoxDataContext = 0x00;
} else {
uctmp = NAK;
biox_Usart3_SendBlock(&uctmp,1);
brd_SendDiagStr("->IUC ASYNCHPOS Sending NACK (Wrong Byte).",1);
return 4; //We got something wrong and it's causing an error
}
}
/*if (iuc_asynchpos_crc_old == rxData_[rxLength - 2]) { //We recieved that package already
iuc_asynchpos_crc_old = 0;
brd_SendDiagStr("->IUC ASYNCHPOS EXCEPTION: double package!",1);
brd_SendDiagStr("->IUC ASYNCHPOS rx data: ",0);
brd_SendDiagBlock(rxData_,1,rxLength);
return 5;
}
iuc_asynchpos_crc_old = rxData_[rxLength - 2];*/
//reformatting according to specs
for (uitemp = 0; uitemp < rxLength; ++uitemp) {
if (rxData_[uitemp] == DLE) {
rxData_[uitemp] = rxData_[uitemp + 1] - 0x30;
for (uitemp2 = uitemp + 2; uitemp2 < rxLength; ++uitemp2) {
rxData_[uitemp2 - 1] = rxData_[uitemp2];
}
--rxLength;
}
}
//Check if we received a logical ACK or NACK
if (rxCounter == 0) {
if (rxData_[3] == 0x0F) {
//NACK recieved, resend message
brd_SendDiagStr("-> IUC ANSNYCHPOS Message NOT ackknowledged",1);
if (asynchState < 0x02) {
iuc_asynchpos_sub_initArray(rxBuf,8);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0xFF;
vmc_SendWithBuffer(rxBuf,3,0x69,0);
}
return 0;
}
if (rxData_[3] == 0x0A) {
//ACK recieved, do nothing
brd_SendDiagStr("-> IUC ANSNYCHPOS Message acknowledged",1);
if (asynchState < 0x02) {
asynchState = 0x02;
iuc_asynchpos_sub_initArray(rxBuf,8);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0x00;
vmc_SendWithBuffer(rxBuf,3,0x69,0);
}
return 0;
}
}
if (rxCounter == 0) {
messageLength = ((UINT) rxData_[1] << 8) | rxData_[2];
if (GWstate.DebugLevel & 0x10)
{
biox_itoa(messageLength,messageLength_);
brd_SendDiagStr("->IUC ASYNCHPOS message length: ",0);
brd_SendDiagBlock(messageLength_,1,8);
}
if (messageLength + 1 < IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE) {
iuc_asynchpos_sub_initArray(messageData, /*messageLength + 1*/ IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE);
} else {
messageLength = 0;
brd_SendDiagStr("->IUC ASYNCHPOS message too long!",0);
//iuc_asynchpos_sub_initArray(messageData, IUC_ASYNCHPOS_MAX_RX_MESSAGE_SIZE);
iuc_asynchpos_sub_initArray(rxBuf,8);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0xFF;
vmc_SendWithBuffer(rxBuf,3,0x69,0);
iuc_asynchpos_resetBuffers(0x00);
return 6;
}
}
if (messageLength > 0) {
//add to rxData
uitemp = 1;
//while (rxData_[uitemp] != ETX1 && rxData_[uitemp] != ETX2 && rxData_[uitemp] != STX) {
while (/*rxData_[uitemp] != 0x02 && rxData_[uitemp] != 0x03*/uitemp < (rxLength - 2)) { //removing the STX, ETX, the checksum and additional zero at the end
rxAsynchData[(uitemp - 1) + rxCounter] = rxData_[uitemp];
++uitemp;
}
rxCounter += uitemp - 1;
if (GWstate.DebugLevel & 0x10)
{
biox_itoa(rxCounter,messageCounter_);
brd_SendDiagStr("->IUC ASYNCHPOS message counter: ",0);
brd_SendDiagBlock(messageCounter_,1,8);
brd_SendDiagStr("->IUC ASYNCHPOS recieve buffer: ",0);
brd_SendDiagBlock(rxAsynchData,1,rxCounter);
}
//NEXT Telegram
if (/*messageLength != 0 && messageLength <= (rxCounter + 5)*/ rxCounter >= (messageLength - 1)) {
if (GWstate.DebugLevel & 0x10)
{
biox_itoa(messageLength,messageLength_);
brd_SendDiagStr("->IUC ASYNCHPOS message length FINAL: ",0);
brd_SendDiagBlock(messageLength_,1,8);
biox_itoa(rxCounter,messageCounter_);
brd_SendDiagStr("->IUC ASYNCHPOS message counter FINAL: ",0);
brd_SendDiagBlock(messageCounter_,1,8);
}
if (rxAsynchData[2] != 0x0A) {
//iuc_asynchpos_sub_initArray(messageReturnData, 100);; //iuc_asynchpos_sub_initArray(messageData, messageLength + 1);//iuc_asynchpos_sub_initArray(messageReturnData, IUC_ASYNCHPOS_MAX_MESSAGE_SIZE);
//if (!iuc_asynchpos_sub_confirm_message(messageData, IUC_ASYNCHPOS_MAX_ARRAY_SIZE))) {
//Send ACK to terminal
//iuc_asynchpos_resetBuffers(0x02);
/*for (uitemp = 0; uitemp < rxAsynchData[11] + 9; ++uitemp) {
messageReturnData[uitemp + 3] = rxAsynchData[uitemp + 3];
}
++uitemp;
//messageReturnData[0] = 0x02;
messageReturnData[0] = uitemp & (0xFF00);
messageReturnData[1] = uitemp & (0x00FF);
messageReturnData[2] = 0x0A;*/
//messageReturnData[uitemp + 2] = ETX1;
//calculate chksum
/*for (uitemp2 = 1; uitemp2 < uitemp + 2; ++uitemp2) {
messageReturnData[uitemp + 3] ^= messageReturnData[uitemp];
}*/
//biox_Usart2_SendBlock(messageReturnData,uitemp + 4);
//brd_SendDiagStr("->IUC ASYNCHPOS message ACKNOWLEDGE: ",0);
//brd_SendDiagBlock(messageReturnData,1,uitemp + 1);
//iuc_asynchpos_send_serial(messageReturnData,uitemp + 1,0x01,0x01);
for (uitemp = 0; uitemp < rxCounter - (12 + rxAsynchData[11]); ++uitemp) {
messageData[uitemp] = rxAsynchData[uitemp + (12 + (UINT) rxAsynchData[11])];
if (messageData[uitemp] == 0x00)
messageData[uitemp] = 0x30;
}
uitemp = biox_FindStrInBufferInt("PrintReceipt",messageData) | biox_FindStrInBufferInt("PRINTRECEIPT",messageData)
| biox_FindStrInBufferInt("AuthorizationResult",messageData) | biox_FindStrInBuffer("AUTHORIZATIONRESULT",messageData);
if (uitemp) {
if (biox_FindStrInBufferInt("PrintReceipt",messageData) | biox_FindStrInBufferInt("PRINTRECEIPT",messageData)) {
biox_CopyBlock(rxAsynchData,3,terminalSignature,0,8);
} else {
biox_CopyBlock(rxAsynchData,3,terminalSignature,8,8);
}
} else {
iuc_asynchpos_sub_sendACK(0);
}
if (GWstate.DebugLevel & 0x10)
{
brd_SendDiagStr("->IUC ASYNCHPOS full message: ",0);
brd_SendDiagBlock(messageData,1,rxCounter - (12 + ((UINT) rxAsynchData[11])));
}
iuc_asynchpos_handleMessage(messageData);
brd_SendDiagStr("-> IUC ANSNYCHPOS Data handled",1);
}
/*brd_SendDiagStr("->IUC ASYNCHPOS full message: ",0);
brd_SendDiagBlock(messageData,1,rxCounter - (12 + rxAsynchData[11]));
iuc_asynchpos_handleMessage(messageData);
brd_SendDiagStr("-> IUC ANSNYCHPOS Data handled",1);*/
iuc_asynchpos_resetBuffers(0x00);
}
}
return 1; //Still busy
}
} //else {
if (ENQrecieved == 0 && (timeInitalized + 10) < GWglobTime.SecOfDay) {
brd_SendDiagStr("->IUC ASYNCHPOS waiting for initialization",1);
biox_Usart3_ClearRecBuffer();
iuc_asynchpos_init();
return 1;
}
if (ism_islocked() && (timeHoldISMAS - GWglobTime.SecOfDay >= 1800))
{
brd_SendDiagStr("->IUC ASYNCHPOS ISMAS holding timeout, ISMAS unlocked!",1);
ism_unlock();
}
if (iuc_asynch_PrintControl == 0xFF) {
iuc_asynch_keepAlive = 0x00;
iuc_asynchpos_sub_sendACK(1);
biox_delay_ms(2);
iuc_asynchpos_sub_sendACK(2);
biox_delay_ms(2);
iuc_asynchpos_command_print_Result(0x01);
biox_delay_ms(2);
if (0x04 == asynchState) { //Was the authorization successful?
brd_SendDiagStr("->IUC ASYNCHPOS Sending YES receipt to VMC.",1);
vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x10); //Yes
} else {
brd_SendDiagStr("->IUC ASYNCHPOS Sending NO receipt to VMC.",1);
vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x20); //No
}
iuc_asynch_PrintControl = 0;
//VendRequest=0;
return 1;
}
/*if (iuc_asynch_PrintControl == 0xFE) {
iuc_asynch_keepAlive = 0x00;
iuc_asynchpos_sub_initArray(rxBuf,8);
rxBuf[0] = 0x45;
rxBuf[1] = 0x00;
rxBuf[2] = 0x00;
vmc_SendWithBuffer(rxBuf,8,0x69,0);
iuc_asynch_PrintControl = 0;
return 1;
}*/
if (rxData_[0] != STX/* && rxLength > 0 && rxData_[0] != 0xFF*/) {
//brd_SendDiagStr("->IUC ASYNCHPOS No STX recieved, ISMAS unlocked, sending NACK!",1);
if (rxData_[0] != 0xFF) {
brd_SendDiagStr("->IUC ASYNCHPOS No STX recieved, ISMAS unlocked!",1);
ism_unlock();
}
biox_Usart3_ClearRecBuffer();
//uctmp = NAK;
//biox_Usart3_SendBlock(&uctmp,1);
}
//Workaround for our terminal problem, which, sometimes, fails to send a Print Result
/*if (0xF0 == iuc_asynch_PrintControl) {
if (0x00 == iuc_asynch_printTimeout) {
iuc_asynchpos_sub_initArray(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
receiptData[0] = 0x50;
if (0x04 == asynchState) { //Was the authorization successful?
vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x10); //Yes
} else {
vmc_SendWithBuffer(receiptData,IUC_ASYNCHPOS_MAX_ARRAY_SIZE,0x69,0x20); //No
}
iuc_asynch_printTimeout = IUC_ASYNCHPOS_PRINTTIMOUT;
iuc_asynch_PrintControl = 0;
} else {
--iuc_asynch_printTimeout;
biox_delay_ms(1);
}
}*/
//}
if (waitforACK)
return 8;
return 0;
}
//messagees
void iuc_asynchpos_sub_synchTime() {
UINT uitemp = 0;
//unsigned char timeStart[] = "2017-12-19 13:40:00";
//biox_CopyBlock(timeStart,0,asynchBill.time,0,biox_StrLen(timeStart));
for (uitemp = 0; uitemp < 6; ++uitemp) {
switch (uitemp) {
case 0: //year
asynchBill.time[2] = (GWglobTime.year / 10) + 0x30;;
asynchBill.time[3] = (GWglobTime.year % 10) + 0x30;
/*#ifdef IUC_ASYCHNPOS_TESTMODE
asynchBill.time[2] = 0x31;
asynchBill.time[3] = 0x39;
#endif*/
break;
case 1: //month
asynchBill.time[5] = (GWglobTime.month / 10) + 0x30;;
asynchBill.time[6] = (GWglobTime.month % 10) + 0x30;
/*#ifdef IUC_ASYCHNPOS_TESTMODE
asynchBill.time[5] = 0x31;
asynchBill.time[6] = 0x32;
#endif*/
break;
case 2: //day
asynchBill.time[8] = (GWglobTime.dayOfMon / 10) + 0x30;;
asynchBill.time[9] = (GWglobTime.dayOfMon % 10) + 0x30;
/*#ifdef IUC_ASYCHNPOS_TESTMODE
asynchBill.time[8] = 0x30;
asynchBill.time[9] = 0x32;
#endif*/
break;
case 3: //hours
asynchBill.time[11] = (GWglobTime.hour / 10) + 0x30;;
asynchBill.time[12] = (GWglobTime.hour % 10) + 0x30;
/*#ifdef IUC_ASYCHNPOS_TESTMODE
asynchBill.time[11] = 0x31;
asynchBill.time[12] = 0x32;
#endif*/
break;
case 4: //minutes
asynchBill.time[14] = (GWglobTime.min / 10) + 0x30;;
asynchBill.time[15] = (GWglobTime.min % 10) + 0x30;
/*#ifdef IUC_ASYCHNPOS_TESTMODE
asynchBill.time[14] = 0x30;
asynchBill.time[15] = 0x30;
#endif*/
break;
case 5: //seconds
asynchBill.time[17] = (GWglobTime.sec / 10) + 0x30;;
asynchBill.time[18] = (GWglobTime.sec % 10) + 0x30;
break;
}
}
}
void iuc_asynchpos_command_ping_terminal() {
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "Ping";
UCHAR tagName[] = "Time";
// UCHAR tagValue[] = "2017-12-19 13:40:00";
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE);
//biox_CopyBlock(UCHAR *src, UINT srcPos, UCHAR *dest, UINT destPos, UINT len);
uitemp = (UCHAR) biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
iuc_asynchpos_sub_synchTime();
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length
++uitemp;
biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value
uitemp += biox_StrLen(asynchBill.time)/* + 1*/;
iuc_asynchpos_send(packetType,message,uitemp,0x00);
}
//80 - d
void iuc_asynchpos_command_Login() { //Kasse registrieren
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "Login";
UCHAR tagName[] = "Time";
//UCHAR tag2Name[] = "IdleText";
UCHAR tag3Name[] = "Flags";
UCHAR tag3Value[] = "AP3";
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE);
uitemp = (UCHAR) biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
//Time
iuc_asynchpos_sub_synchTime();
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length
++uitemp;
biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value
uitemp += biox_StrLen(asynchBill.time);
//Flags
message[uitemp] = (UCHAR) biox_StrLen(tag3Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name));// tag name
uitemp += (1 + biox_StrLen(tag3Name));
message[uitemp] = (UCHAR) biox_StrLen(tag3Value);//value length
++uitemp;
biox_CopyBlock(tag3Value,0,message,uitemp, biox_StrLen(tag3Value));//value
uitemp += biox_StrLen(tag3Value)/* + 1*/;
iuc_asynchpos_send(packetType,message,uitemp,0x01);
}
//81 - d
void iuc_asynchpos_command_Logout () { //Kassenschluss
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "Logout";
UCHAR tagName[] = "Time";
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE);
uitemp = (UCHAR) biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
iuc_asynchpos_sub_synchTime();
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length
++uitemp;
biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value
uitemp += biox_StrLen(asynchBill.time)/* + 1*/;
iuc_asynchpos_send(packetType,message,uitemp,0x01);
asynchState = 0x00;
}
//54 - d
void iuc_asynchpos_command_authorize(unsigned int vkPreis) {
UCHAR message[IUC_ASYNCHPOS_MAX_ARRAY_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "Authorize";
UCHAR tag1Name[] = "Amount";
UCHAR tag2Name[] = "Cash";
UCHAR tag3Name[] = "Currency";
UCHAR tag4Name[] = "DocNr";
UCHAR tag5Name[] = "Time";
UCHAR tag6Name[] = "Lang";
UCHAR tag1Value[10];
UCHAR tag2Value[] = "0";
UCHAR tag3Value[] = "978";
UCHAR tag6Value[] = "lt";
UINT vkPreis_ = vkPreis;
iuc_asynch_PRNrecieved = 0;
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_ARRAY_SIZE);
iuc_asynchpos_sub_initArray(tag1Value,10);
uitemp = (UCHAR) biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
//Amount
message[uitemp] = (UCHAR) biox_StrLen(tag1Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag1Name,0,message,uitemp, biox_StrLen(tag1Name));// tag name
uitemp += (1 + biox_StrLen(tag1Name));
biox_itoa(vkPreis_,tag1Value);
message[uitemp] = (UCHAR) biox_StrLen(tag1Value);//value length
++uitemp;
biox_CopyBlock(tag1Value,0,message,uitemp, biox_StrLen(tag1Value));//value
uitemp += (/*1 + */biox_StrLen(tag1Value));
//Cash
message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name
uitemp += (1 + biox_StrLen(tag2Name));
message[uitemp] = (UCHAR) biox_StrLen(tag2Value);//value length
++uitemp;
biox_CopyBlock(tag2Value,0,message,uitemp, biox_StrLen(tag2Value));//value
uitemp += (/*1 + */biox_StrLen(tag2Value));
//Currency
message[uitemp] = (UCHAR) biox_StrLen(tag3Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag3Name,0,message,uitemp, biox_StrLen(tag3Name));// tag name
uitemp += (1 + biox_StrLen(tag3Name));
message[uitemp] = (UCHAR) biox_StrLen(tag3Value);//value length
++uitemp;
biox_CopyBlock(tag3Value,0,message,uitemp, biox_StrLen(tag3Value));//value
uitemp += (/*1 + */biox_StrLen(tag3Value));
//DocNr
message[uitemp] = (UCHAR) biox_StrLen(tag4Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag4Name,0,message,uitemp, biox_StrLen(tag4Name));// tag name
uitemp += (1 + biox_StrLen(tag4Name));
//biox_ltoa(asynchBill.docuNr,asynchBill.docNr);
//++asynchBill.docuNr;
generate_UniqueTransNr(asynchBill.docNr);
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length
++uitemp;
biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value
uitemp += biox_StrLen(asynchBill.docNr)/* + 1*/;
//Time
message[uitemp] = (UCHAR) biox_StrLen(tag5Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag5Name,0,message,uitemp, biox_StrLen(tag5Name));// tag name
uitemp += (1 + biox_StrLen(tag5Name));
iuc_asynchpos_sub_synchTime();
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.time);//value length
++uitemp;
biox_CopyBlock(asynchBill.time,0,message,uitemp, biox_StrLen(asynchBill.time));//value
uitemp += biox_StrLen(asynchBill.time)/* + 1*/;
//Language
message[uitemp] = (UCHAR) biox_StrLen(tag6Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag6Name,0,message,uitemp, biox_StrLen(tag6Name));// tag name
uitemp += (1 + biox_StrLen(tag6Name));
message[uitemp] = (UCHAR) biox_StrLen(tag6Value);//value length
++uitemp;
biox_CopyBlock(tag6Value,0,message,uitemp, biox_StrLen(tag6Value));//value
uitemp += biox_StrLen(tag6Value)/* + 1*/;
iuc_asynchpos_send(packetType,message,uitemp,0x00);
}
//73 - d
void iuc_asynchpos_command_cancel_authorize() {
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "AuthorizationCancelled";
UCHAR tagName[] = "ID";
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE);
uitemp = biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
if (asynchBill.id[0] != 0x00) {
++uitemp;
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.id);//value length
++uitemp;
biox_CopyBlock(asynchBill.id,0,message,uitemp, biox_StrLen(asynchBill.id));//value
uitemp += biox_StrLen(asynchBill.id)/* + 1*/;
}
iuc_asynchpos_send(packetType,message,uitemp,0x00);
}
//77 - d
void iuc_asynchpos_command_close_Document(unsigned char isStorno) { //Finalize sale
UCHAR message[IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE];
UCHAR packetType = 0x00;
UINT uitemp = 0;
UCHAR command[] = "DocClosed";
UCHAR tagName[] = "DocNr";
UCHAR tag2Name[] = "AuthID";
//Constructing the message
iuc_asynchpos_sub_initArray(message,IUC_ASYNCHPOS_MAX_TX_MESSAGE_SIZE);
uitemp = biox_StrLen(command);
message[0] = (UCHAR) uitemp + 0x80; //constructed element, tag name length
biox_CopyBlock(command,0,message,1,uitemp); //tag name
++uitemp;
//DocNr
message[uitemp] = (UCHAR) biox_StrLen(tagName);//data element, tag name length
++uitemp;
biox_CopyBlock(tagName,0,message,uitemp, biox_StrLen(tagName));// tag name
uitemp += (1 + biox_StrLen(tagName));
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.docNr);//value length
++uitemp;
biox_CopyBlock(asynchBill.docNr,0,message,uitemp, biox_StrLen(asynchBill.docNr));//value
uitemp += biox_StrLen(asynchBill.docNr);
//AuthID
if (!isStorno) {
message[uitemp] = (UCHAR) biox_StrLen(tag2Name);//data element, tag name length
++uitemp;
biox_CopyBlock(tag2Name,0,message,uitemp, biox_StrLen(tag2Name));// tag name
uitemp += (1 + biox_StrLen(tag2Name));
message[uitemp] = (UCHAR) biox_StrLen(asynchBill.id);//value length
++uitemp;
biox_CopyBlock(asynchBill.id,0,message,uitemp, biox_StrLen(asynchBill.id));//value
uitemp += biox_StrLen(asynchBill.id)/* + 1*/;
}
iuc_asynchpos_send(packetType,message,uitemp,0x00);
}
void iuc_asynchpos_handleCommand(unsigned char command, unsigned char status) {
//r - registration, a - authorization, c - cancel, s - storno, k - kassenschnitt
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;
}
}
int iuc_asynchpos_checkTime() {
int retVal = 0;
if ((GWglobTime.hour == 0) && asynchSessionClosed != 0x00) {
asynchSessionClosed = 0x00;
retVal = 1;
} else if ((GWglobTime.hour == 1) && asynchSessionClosed == 0x00) {
iuc_asynchpos_command_Logout();
retVal = 1;
asynchSessionClosed = 0x01;
} else if ((GWglobTime.hour == 2) && asynchSessionClosed == 0x01) {
iuc_asynchpos_command_Login();
retVal = 1;
asynchSessionClosed = 0x02;
}
return retVal;
}
unsigned char iuc_asynchpos_getIsSaleRunning() {
//Print, when idle
/*if (iuc_print_counter && asynchState == 0x01) {
iuc_asynchpos_command_print_Result(0x01);
--iuc_print_counter;
return 1;
}*/
return iuc_asynch_keepAlive;
}
#endif