#include "runProc.h" #include #include "controlBus.h" #include "dcBL.h" static uint32_t hwapi_lastStartAmount; static uint32_t hwapi_lastTotalAmount; static uint8_t hwapi_cash_lastCollectionState; static uint8_t hwapi_paymentStarted; static uint8_t hwapi_lastDoorState; static uint8_t bl_startupStep; T_runProc::T_runProc() { hwapi_TimerPayment = new QTimer(); hwapi_TimerPayment->setSingleShot(true); hwapi_lastStartAmount=0; hwapi_lastTotalAmount=0; hwapi_cash_lastCollectionState=0; hwapi_paymentStarted=0; hwapi_lastDoorState=0; bl_startupStep=0; QTimer *runProc_callProcesses = new QTimer(); connect(runProc_callProcesses, SIGNAL(timeout()), this, SLOT(runProc_slotProcess())); runProc_callProcesses->setSingleShot(false); runProc_callProcesses->start(10); // in ms hwapi_lastDoorState=0; // default: all doors (should be) closed, coin box inserted // bit0: upper door 1:middle 2:lower 3=cash-box out myTO = new QTimer(); myTO->setSingleShot(true); myTO->start(200); } void T_runProc::runProc_slotProcess(void) { #ifndef THIS_IS_CA_MASTER bool const coinAttached = epi_getDI_CoinAttach(); // exchange: (atomically) replaces the underlying value of m_coinAttached // with the value of coinAttached, returns the value of m_coinAttached // before the call if (m_coinAttached.exchange(coinAttached) == false) { if (coinAttached) { // old value was false, and new value is true emit runProc_coinAttached(); } } cash_paymentProcessing(); doors_supervise(); bl_performComplStart(); // neu 1.12.23 dcBL_cycle(); prn_directTicket_cycle(); #endif } bool T_runProc::cash_startPayment(uint32_t amount) { uint8_t dat1, dat2, dat3, dat4; hwapi_lastStartAmount=amount; epi_clearCurrentPayment(); dat1=ulong2uchar(amount, 0); dat2=ulong2uchar(amount, 1); dat3=ulong2uchar(amount, 2); dat4=ulong2uchar(amount, 3); hwapi_cash_lastCollectionState=0; sendFDcmd_set(155, 0,0, dat1,dat2,dat3,dat4); // wird im DC auf 65500 gesetzt wenn 0 (Maximalwert 0 macht keinen Sinn!) hwapi_paymentStarted=1; hwapi_TimerPayment->start(5000); // in ms hwapi_lastTotalAmount=0; epi_setNowCoinPay(true); // new since 20.9.23 qDebug() << "payment started with " << amount ; return true; } uint8_t T_runProc::cash_paymentProcessing(void) { // run this function periodically while coin payment process to generate necessary signals: // am 5.10.23 umgebaut, geht jetzt auch fuer MW. Für EMP und MW getestet // 12.10.23: epi_store64BdevParameter() MUSS vorher aufgerufen werden zur Unterscheidung EMP / MW !!!!! // return value: // 0: stopped 1: starting up 2: coin collection // 3: finished by User (Push button) 4: finished, Max-Value collected // 5: finished by escrow // 6: money encashed // 7: cancelled // 10,11: error cannot start // 12: timeout while payment, coins returned // 13: stopped by unexpected error struct T_emp empStat; struct T_changer chgrStat; struct T_dynamicCondition myDynMachCond; struct T_devices devParameter; uint8_t collActiv=0, payInProg, kcc; // empState uint32_t newSum; if (hwapi_paymentStarted<1) return 0; // off collActiv=1; // starting up payment devParameter.kindOfCoinChecker=0; restoreDeviceParameter(&devParameter); kcc=devParameter.kindOfCoinChecker; /* buf66[0]=devPara.kindOfPrinter; buf66[1]=devPara.kindOfCoinChecker; buf66[2]=devPara.kindOfMifareReader; buf66[3]=devPara.suppressSleepMode; buf66[4]=devPara.kindOfModem; buf66[5]=devPara.kindOfCreditcard; buf66[6]=devPara.CoinEscrow; buf66[7]=devPara.CoinRejectUnit; buf66[8]=devPara.CoinShutter; buf66[9]=devPara.BillAcceptor; buf66[10]=devPara.usevaultLock; buf66[11]=devPara.autoAlarm; buf66[12]=devPara.autoOpen; buf66[13]=devPara.printAccReceipt; buf66[14]=devPara.printDoorReceipt; buf66[15]=devPara.printTokenTicket; uitmp=devPara.VaultFullWarnLevel; buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT); buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); uitmp=devPara.VaultFullErrorLevel; buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT); buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); */ if (kcc<3) { sub_emp_getAllParameters(&empStat); //empState=empStat.state; } else { changer_getAllParameters(&chgrStat); //empState=chgrStat.state; } // 0=start command // 1=powered, do emp ini, send reset // 2=delay // 3=wait for response, requesting status after response // 4,5 through, startup // 6: wait for status // 7: through, startup // 8: IDLE state. EMP is up and ready, polling is running // 9: polling on, payment not yet on // 10: payment, check coins // 11: through // 12: wait 1s for last coin // 90: stop all, 1s delay // 99: off, all stopped sub_getDynMachineConditions(&myDynMachCond); payInProg= myDynMachCond.paymentInProgress; // Version Szeged: aug2023 // 0: stopped by timeout // 1: running 2: wait4lastCoin // 3: payment stopped manually, coins in Escrow // 4: payment stopped autom, amount collected, coins in Escrow // 5: payment stopped, escrow full, coins in Escrow // 6: coins encashed // 7: coins returned 2 cases: due to cancel-button or printer-error // 8: CoinChecker or MDB on Error // since Schoenau with bill and changer, nov2023 //0 = no payment //will be set to 1 by cash_startCollection() //neu 1: wait for devices getting ready for payment //2 = payment, //3 = wait for last coin/bill //4 = Bezahlvorgang manuell beendet //5 = payment stopped autom, amount collected, coins in Escrow //6 = Bezahlvorgang beendet weil ZK voll //4,5,6: payment done, keep on polling, wait for cash or return command //7 = encash collected money from coin escrow into cash box //8 = return "amountToReturn", can be complete inserted amount or only overpayment //9 = wait for changer result //10= print refund receipt with "amountToReturn" // if (empState>=10 && empState<=12 && (payInProg==1 || payInProg==2) ) // Szeged if ( payInProg==2 ) //8.12.23 { // coin acceptance is active now: if (hwapi_paymentStarted==1) // && (( payInProg==0) || ( payInProg>5))) //16.6.23 { // 1=wait for coin checker being ready hwapi_paymentStarted=2; // coins can be inserted now qCritical() << "emitting signal coinCollectionJustStarted"; emit runProc_coinCollectionJustStarted(); } } if (hwapi_paymentStarted==2) { // coins can be inserted now, wait for end collActiv=2; // coin collection active newSum=epi_CurrentPaymentGetAmount(); if (newSum>hwapi_lastTotalAmount) { hwapi_lastTotalAmount=newSum; qCritical() << "emitting signal gotNewCoin"; emit runProc_gotNewCoin(); } if (payInProg==0) // timeout, coins returned by DC { hwapi_paymentStarted=90; collActiv=12; // stop by timeout qCritical() << "emitting signal payStopByTimeout"; emit runProc_payStopByTimeout(); } else if (payInProg==4) // user pressed "Next/Continue", keep coin since nov2023 { hwapi_paymentStarted++; collActiv=3; qCritical() << "emitting signal payStopByPushbutton 1"; emit runProc_payStopByPushbutton(); } else if (payInProg==5) // max achieved, keep coins since nov2023 { hwapi_paymentStarted++; collActiv=4; qCritical() << "emitting signal payStopByMax"; emit runProc_payStopByMax(); } else if (payInProg==6) // escrow full, keep coins since nov2023 { hwapi_paymentStarted++; collActiv=5; qCritical() << "emitting signal payStopByEscrow"; emit runProc_payStopByEscrow(); } } if (hwapi_paymentStarted==3) { // coin collection finished, but coins kept until printing done collActiv=2; if (payInProg==7) // coins encashed since nov2023 { collActiv=6; hwapi_paymentStarted++; qCritical() << "emitting signal coinProcessJustStopped"; emit runProc_coinProcessJustStopped(); } else if (payInProg==0) // coins returned, printing failed since nov2023 { collActiv=7; hwapi_paymentStarted++; qCritical() << "emitting signal payCancelled"; emit runProc_payCancelled(); } } if (hwapi_paymentStarted==4) { // transaction finished hwapi_paymentStarted=0; } if (hwapi_paymentStarted==90 ) { // EMP error, wait till process finished // everything stopped, no more coins in escrow hwapi_paymentStarted=0; } return collActiv; } void T_runProc::sub_emp_getAllParameters(struct T_emp *emp) { uint8_t leng, data[66], ii, pp; epi_restoreEmpSettings(&leng, data); // expected length = 64 byte // get 64 bytes about EMP: see h-file emp->gotSetup = data[0]; emp->state = data[1]; emp->shaft = data[2]; emp->countryCode= uchar2uint(data[4], data[3]); emp->scale = data[5]; emp->decimals = data[6]; for (ii=0; ii<16; ii++) emp->coinValues[ii] = data[7+ii]; emp->coinAccept = uchar2uint(data[24], data[23]); emp->tokenChannel = data[25]; emp->pollingRunning = data[26]; emp->paymentRunning = data[27]; pp=28; for (ii=0; ii<16; ii++) { emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]); pp+=2; } emp->routing= uchar2uint(data[61], data[60]); } void T_runProc::changer_getAllParameters(struct T_changer *mw) { // requested automatically with 23, same like EMP uint8_t leng, data[66], pp, nn; epi_restoreEmpSettings(&leng, data); // expected length = 64 byte // get 64 bytes about Changer (mw), see interfaces.h-file mw->setup = data[0]; mw->state = data[1]; mw->level = data[2]; mw->countryCode = uchar2uint(data[4], data[3]); mw->scale = data[5]; mw->decimals= data[6]; for (nn=0; nn<16; nn++) mw->coinSetup[nn]= data[nn+7]; // 7...22 mw->intendedAcceptance = uchar2uint(data[24], data[23]); mw->tokenChannel= data[25]; mw->pollingRunning= data[26]; mw->paymentRunning= data[27]; pp=28; for (nn=0; nn<16; nn++) { mw->denomination[nn] = uchar2uint(data[pp+1], data[pp]); pp+=2; } // bis pp=60 mw->availableTubes = uchar2uint(data[61], data[60]); } void T_runProc::sub_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) { uint16_t LL, nn; char *start; uint8_t buf[70], leng; tslib_strclr(buf,0,70); epi_restoreDynMachineConditions(&leng, buf); // Puffer in struct eintragen: LL=sizeof(struct T_dynamicCondition); start = &dynMachCond->allDoorsDebounced; if (LL>64) LL=64; if (leng>64) leng=64; nn=0; do { *start = buf[nn]; start++; } while(++nnkindOfPrinter; nn=0; do { *start = buf[nn]; start++; } while(++nn16000)) // 8...16V erlaubt return false; // Fehler if ((myDynMachCond.Temperatur<40) || (myDynMachCond.Temperatur>260)) // -30°C...80°C erleubt return false; // Fehler uctmp=(hwapi_lastDoorState & 1); // 0: upper door is closed if (uctmp==0 && myDynMachCond.upperDoor>0) { hwapi_lastDoorState |= 1; qCritical()<<"hwapi emitting signal ServiceDoorOpened"; emit runProc_doorServiceDoorOpened(); } uctmp=(hwapi_lastDoorState & 2); if (uctmp==0 && myDynMachCond.middleDoor>0) { hwapi_lastDoorState |= 2; qCritical()<<"hwapi emitting signal VaultDoorOpened "; emit runProc_doorVaultDoorOpened(); } uctmp=(hwapi_lastDoorState & 4); if (uctmp==0 && myDynMachCond.lowerDoor>0) { hwapi_lastDoorState |= 4; qCritical()<<"hwapi emitting signal ServiceDoorOpened (Batt)"; emit runProc_doorServiceDoorOpened(); } uctmp=(hwapi_lastDoorState & 8); // 0: cash box was in if (uctmp==0 && myDynMachCond.CBinDebounced==0) // 0:fehlt 1:drin { // Kasse wurde gerade entnommen hwapi_lastDoorState |= 8; qCritical()<<"hwapi emitting signal CoinBoxRemoved "; emit runProc_doorCoinBoxRemoved(); } uctmp=(hwapi_lastDoorState & 8); if (uctmp>0 && myDynMachCond.CBinDebounced>0) // 0:fehlt 1:drin { // Kasse war draussen, ist wieder drin hwapi_lastDoorState &= ~0x08; qCritical()<<"hwapi emitting signal CoinBoxInserted"; emit runProc_doorCoinBoxInserted(); } uctmp=(hwapi_lastDoorState & 0x07); doorTemp=0; if (myDynMachCond.upperDoor>0) doorTemp |=1; if (myDynMachCond.middleDoor>0) doorTemp |=2; if (myDynMachCond.lowerDoor>0) doorTemp |=4; if (uctmp>0 && doorTemp==0) // vorher war mind. EINE Tuer offen UND jetzt sind alle zu { hwapi_lastDoorState &= ~0x07; // soeben wurde die letzte Tür geschlossen, prüfe ob Kasse eingesetzt wurde: if (myDynMachCond.CBinDebounced) { qCritical()<<"hwapi emitting signal CBinAndAllDoorsClosed"; emit runProc_doorCBinAndAllDoorsClosed(); hwapi_lastDoorState &=~0x08; // keine Wirkung } else { qCritical()<<"hwapi emitting signal AllDoorsClosed"; emit runProc_doorAllDoorsClosed(); } } return true; } uint8_t T_runProc::prn_getHwState(struct Tprn_hw_state *prn_hw_state) { // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok? // printer on error or ok? uint8_t prnHWstate[20]; epi_restorePrinterState(prnHWstate); // byte 0: 0:unknown 1: printer OK 100: printer OK but paper near end // 200: not connected 201: printer on error 202: no paper // byte 1 = 0: prnter OK, >0: error // bit0: paper low 1: no paper 2: temperature error // 3: head open 4: paper jam in cutter // 6: no response 7: bad response from printer // byte 2..6 come right from printer, by now always 0 prn_hw_state->powerRdBk = epi_getDI_printerPwr(); prn_hw_state->rsSwOk = epi_getDO_serialMux1isSetToPrinter(); // mux1 off: serial is switched to printer prn_hw_state->rsDrvOk = epi_getDO_serialDriverIsOn(); prn_hw_state->ReadyLine = epi_getDI_prnReady(); if (prnHWstate[1]<2) prn_hw_state->inIdle = true; // no errors else prn_hw_state->inIdle = false; // off or errors if (prnHWstate[1] & 1) prn_hw_state->paperNearEnd=true; else prn_hw_state->paperNearEnd = false; if (prnHWstate[1] & 2) prn_hw_state->noPaper=true; else prn_hw_state->noPaper = false; if (prnHWstate[1] & 4) prn_hw_state->ErrorTemp=true; else prn_hw_state->ErrorTemp = false; if (prnHWstate[1] & 8) prn_hw_state->HeadOpen=true; else prn_hw_state->HeadOpen = false; if (prnHWstate[1] & 16) prn_hw_state->cutterJam=true; else prn_hw_state->cutterJam = false; if (prnHWstate[1] & 64) prn_hw_state->noResponse=true; else prn_hw_state->noResponse = false; if (prnHWstate[1] & 128) prn_hw_state->badResponse=true; else prn_hw_state->badResponse = false; return prnHWstate[0]; } void T_runProc::dc_autoRequest(bool on) { // automatically request ALL digital and analog sensors, get time/date, get status information epi_startEmmision(on); } void T_runProc::bl_rebootDC(void) { // send command to normal DC-Program requesting a restart // BL is working for 5s after power-on-reset. uint8_t len, buf[20]; len=dcBL_restartDC(buf); sendWRcmd_setSendBlock160(len, buf); } void T_runProc::bl_startBL(void) { // use this function within the first 5s after reboot to startup the BL, // otherwise the BL jumps to normal DC application uint8_t len, buf[20]; len=dcBL_activatBootloader(buf); sendWRcmd_setSendBlock160(len, buf); epi_setNowIsBootload(true); } void T_runProc::bl_checkBL(void) { // call this function in order to get information, afterwards use "bl_isUp()" uint8_t len, buf[20]; len=dcBL_readFWversion(buf); sendWRcmd_setSendBlock160(len, buf); } bool T_runProc::bl_isUp(void) { uint8_t receivedData[160]; uint8_t LL, nn; for (nn=0; nn<160; nn++) receivedData[nn]=0; LL=epi_getRawRecLength(); if (LL>0) { epi_getRawReceivedData(receivedData); // response to "readFWversion" if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 && receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176) { qDebug() << "got BL response to readFWversion"; //epi_clrRawReceivedString(); return true; } // response to "start BL" if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 && receivedData[3]==223 && receivedData[4] ==131 ) { qDebug() << "hwapi_bl_isUp: got BL response to start"; //epi_clrRawReceivedString(); return true; } } return false; } void T_runProc::bl_completeStart(void) { bl_startupStep=1; } bool T_runProc::bl_performComplStart(void) { bool result; static uint8_t retryCtr; if ((bl_startupStep<1) || (bl_startupStep>10)) return false; if (bl_startupStep==1) { dc_autoRequest(false); bl_startupStep++; } else if (bl_startupStep==2) { qDebug()<<"rebooting"; bl_rebootDC(); myTO->stop(); myTO->start(500); retryCtr=0; bl_startupStep++; } else if (bl_startupStep==3) { if (!myTO->isActive()) { qDebug()<<"starting BL"; bl_startBL(); myTO->stop(); myTO->start(500); bl_startupStep++; } } else if (bl_startupStep==4) { if (!myTO->isActive()) { qDebug()<<"checking BL"; bl_checkBL(); myTO->stop(); myTO->start(200); bl_startupStep++; } } else if (bl_startupStep==5) { if (!myTO->isActive()) { qDebug()<<"step 5"; result = bl_isUp(); qDebug()<<"BL result: "<< result; if (result) { bl_startupStep=99; qDebug()<<"BL is working now..."; // BL is up and running return true; } else { retryCtr++; // start again if (retryCtr>=10) { bl_startupStep=99; qDebug()<<"BL error!!!"; } else { bl_startupStep=3; myTO->stop(); myTO->start(200); qDebug()<<"BL retry..."; } } } } return false; } // new from 21.5.24 .................................................................. uint16_t T_runProc::sys_getCustomerNumber(void) { uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location return uchar2uint(data[1], data[0]); } uint16_t T_runProc::sys_getMachineNumber(void) { uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location return uchar2uint(data[3], data[2]); } uint16_t T_runProc::sys_getBoroughNumber(void) { uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location return uchar2uint(data[5], data[4]); } uint16_t T_runProc::sys_getZoneNumber(void) { uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location return uchar2uint(data[7], data[6]); } uint16_t T_runProc::sys_getMachineAlias(void) { uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location return uchar2uint(data[9], data[8]); } void T_runProc::sys_getLocation(char *locStr) { // return location in "locStr[32]" uint8_t length, data[64]; epi_restoreMachineIDsettings(&length, data); // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name // byte[10...41]=location for (int nn=0; nn<32; nn++) locStr[nn]=data[nn+10]; } void T_runProc::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) { // send 5 byte: byte 0,1: speed 5...250 mm/s // byte2: density 0....(25)....50 // byte3: alignment 'l', 'c', 'r' = left, center, right // byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) uint8_t buf[10]; uint16_t uitmp; uitmp=paperSpeed; buf[0]=uint8_t(uitmp); uitmp>>=8; buf[1]=uint8_t(uitmp); buf[2]=density; buf[3]=alignment; buf[4]=orientation; buf[5]=0; longFDcmd_set(CMD2DC_PRI_SETUP,0,0,5, buf); } void T_runProc::prn_sendText(QByteArray *buf) { uint16_t nn, pp, mm, leng_byt, llb, freeStak, anzahlFullBlocks; uint8_t tmp66[66]; //qCritical() << __PRETTY_FUNCTION__ << "RESET DC DATA VALID"; epi_clearDynMachineConditions(); // 24.6.23 gpi_storeDcDataValid(0); memset(tmp66,0,66); leng_byt=buf->size(); freeStak=check4freeFDstack(); freeStak<<=6; if ( leng_byt > freeStak) { leng_byt=freeStak; // shorten the buffer as we cannot return an error (void function) } llb=leng_byt % 64; // length of last block, >0 if not dividable by 64 anzahlFullBlocks=leng_byt / 64; pp=0; for (nn=0; nnat(pp++); longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,64, tmp66); } if (llb>0) { // last block is shorter, only llb bytes memset(tmp66,0,66); for (mm=0; mmat(pp++); for (mm=llb; mm<64; mm++) tmp66[mm]=0; longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,llb, tmp66); // set real length, not 64 } } void T_runProc::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) { // send three byte through to printer, see printers manual //sendWRcmd _setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3); hat gar nicht funktioniert uint8_t data[64]; uint32_t ultmp=para3; memset(data, 0,64); data[0]=para1; data[1]=para2; data[2]=0; data[3]=0; data[4]=uint8_t(ultmp); ultmp>>=8; data[5]=uint8_t(ultmp); ultmp>>=8; data[6]=uint8_t(ultmp); ultmp>>=8; data[7]=uint8_t(ultmp); longFDcmd_set(CMD2DC_PRI_SYS_CMD, 0, 0, 8, data); // getestet auf richtige uebertragung am 11.9.23TS } void T_runProc::prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) { uint8_t buf[66], nn; if (dataLeng>58) dataLeng=58; buf[0]=kindOf; buf[1]=withText; buf[2]=offset; buf[3]=rotation; buf[4]=dataLeng; // rest: Barcode-data: for (nn=0; nn= fileLength) break; // search for ":" (quote comma quote) // copy content to array keyStr up to there ps=0; do { oneSign=localCopy.at(filePointer++); runProc_prnFile[LL].keyStr[ps++]=oneSign; } while(oneSign!=':' && filePointer= fileLength) break; // found : // search for ", or " NL=10 or 13 or both (quote and new line) // copy content to array valStr up to there // skip ",": if (filePointer < (fileLength-1)) { filePointer++; } if (filePointer >= fileLength) break; ps=0; do { oneSign=localCopy.at(filePointer++); runProc_prnFile[LL].valStr[ps++]=oneSign; } while( (oneSign!='"' && oneSign!=10 && oneSign!=13) && filePointer16) runProc_nrOfPrnDyns=16; for (pp=0; pp=runProc_nrOfPrnDyns || pp>15) return false; for (nn=0; nn1024) sl=1024; textLine[sl]=0; uint16_t point; if (sl==0) return 10000; point=runProc_prnSeqNr; if (point>127) { runProc_prnSeqNr=0; point=0; } runProc_prnTextSeq[runProc_prnSeqNr].clear(); runProc_prnTextSeq[runProc_prnSeqNr++].append(textLine); return point; // Text wurde an diese Stelle geschrieben } void T_runProc::sub_changeStyle(char *valueStr) { /* "styl":"bold on", "styl":"under off", "styl":"latin on", "styl":"font 12", // select Font-type for the following print, / range: 1...99 "styl":"size 01", // select Font size for the following print // range: 00...99, depends on font-type, selects hight and width // 10th:height 1th=width "styl":"align c" // 'l' 'c' 'r' // left center right "styl":"density25"; // 0....[25]...50 0=blass */ uint8_t val; if (runProc_pointPrnCmd >= 510) { // do nothing, buffer is full } else if ( memcmp(valueStr, "bold on", 7) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=10; // cmd 10 heisst "bold on" } else if ( memcmp(valueStr, "bold off", 7) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=11; // cmd 11 heisst "bold off" } else if ( memcmp(valueStr, "under on", 8) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=12; } else if ( memcmp(valueStr, "under off", 8) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=13; } else if ( memcmp(valueStr, "latin on", 8) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=14; } else if ( memcmp(valueStr, "latin off", 8) ==0 ) // ==0 means equal { runProc_prnCmdSeq[runProc_pointPrnCmd++]=15; } else if ( memcmp(valueStr, "font ", 5) ==0 ) // font type { valueStr[7]=0; val=uint8_t(tslib_atol(&valueStr[5])); runProc_prnCmdSeq[runProc_pointPrnCmd]=16; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "size ", 5) ==0 ) { valueStr[7]=0; val=uint8_t(tslib_atol(&valueStr[5])); runProc_prnCmdSeq[runProc_pointPrnCmd]=17; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "align ", 6) ==0 ) { runProc_prnCmdSeq[runProc_pointPrnCmd]=18; runProc_prnCmdPara[runProc_pointPrnCmd++]=valueStr[6]; } else if ( memcmp(valueStr, "density", 7) ==0 ) { valueStr[9]=0; val=uint8_t(tslib_atol(&valueStr[7])); runProc_prnCmdSeq[runProc_pointPrnCmd]=19; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } // "prn_papSped" comes with feed-cmd, not with "styl" !! } char T_runProc::subFeedPaper(char *valueStr) { uint16_t val; /* "feed":"cut", "feed":"part", "feed":"eject", // 5 line forward and cut "feed":"line3", // 3 line forward (1..9) "feed":"back1", // 1 line back (1..9) "feed":"BM", // Blackmark "feed":"nl", // NewLine LF & CR (1..9) "feed":"margin05", // left border in mm "feed":"rim05", // right border in mm "feed":"speed10", // printer speed *10mm/s */ if (runProc_pointPrnCmd >= 510) { // do nothing, buffer is full } else if ( memcmp(valueStr, "cut", 3) ==0 ) { runProc_prnCmdSeq[runProc_pointPrnCmd++]=30; } else if ( memcmp(valueStr, "part", 4) ==0 ) { runProc_prnCmdSeq[runProc_pointPrnCmd++]=31; } else if ( memcmp(valueStr, "eject", 5) ==0 ) { runProc_prnCmdSeq[runProc_pointPrnCmd++]=32; } else if ( memcmp(valueStr, "line", 4) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[4])); runProc_prnCmdSeq[runProc_pointPrnCmd]=33; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "back", 4) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[4])); runProc_prnCmdSeq[runProc_pointPrnCmd]=34; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "BM", 2) ==0 ) { runProc_prnCmdSeq[runProc_pointPrnCmd++]=35; } else if ( memcmp(valueStr, "nl", 2) ==0 ) { // immer eine Zeile vor, Para=1!!! runProc_prnCmdSeq[runProc_pointPrnCmd]=36; runProc_prnCmdPara[runProc_pointPrnCmd++]=1; //return 'n'; } else if ( memcmp(valueStr, "margin", 6) ==0 ) { valueStr[8]=0; val=uint8_t(tslib_atol(&valueStr[6])); runProc_prnCmdSeq[runProc_pointPrnCmd]=37; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "rim", 3) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[3])); runProc_prnCmdSeq[runProc_pointPrnCmd]=38; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "speed", 5) ==0 ) { valueStr[7]=0; val=uint8_t(tslib_atol(&valueStr[5])); val*=10; runProc_prnCmdSeq[runProc_pointPrnCmd]=39; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } return 0; } void T_runProc::subPrintGrafics(char *valueStr) { uint16_t val; /* graf":"barc8", // kind and content is fixed programmed, 1..9 "graf":"logo2", // programmed in printer, 1...9 "graf":"q.r.1", // content is fixed programmed 1..9 */ if (runProc_pointPrnCmd >= 510) { // do nothing, buffer is full } else if ( memcmp(valueStr, "barc", 4) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[4])); runProc_prnCmdSeq[runProc_pointPrnCmd]=50; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "logo", 4) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[4])); runProc_prnCmdSeq[runProc_pointPrnCmd]=51; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } else if ( memcmp(valueStr, "q.r.", 4) ==0 ) { valueStr[5]=0; val=uint8_t(tslib_atol(&valueStr[4])); runProc_prnCmdSeq[runProc_pointPrnCmd]=52; runProc_prnCmdPara[runProc_pointPrnCmd++]=val; } } bool T_runProc::subGetVariStr(char *valueStr, char *returnStr) { // return appropriate value as string in returnStr[32] uint16_t val; uint8_t ddnum; uint8_t hh, min, ss, yy, mon, dd; uint8_t dow, datebuf[16]; uint16_t minOfToday; uint32_t secOfToday; for (int nn=0; nn<32; nn++) returnStr[nn]=0; for (int nn=0; nn<16; nn++) datebuf[nn]=0; // 1) fix data if ( memcmp(valueStr, "cunu", 4) ==0 ) // ==0 means equal { val=sys_getCustomerNumber(); tslib_uitoa(val,returnStr); return true; } if ( memcmp(valueStr, "manu", 4) ==0 ) // ==0 means equal { val=sys_getMachineNumber(); tslib_uitoa(val,returnStr); return true; } if ( memcmp(valueStr, "group", 5) ==0 ) // ==0 means equal { val=sys_getBoroughNumber(); tslib_uitoa(val,returnStr); return true; } if ( memcmp(valueStr, "zone", 4) ==0 ) // ==0 means equal { val=sys_getZoneNumber(); tslib_uitoa(val,returnStr); return true; } if ( memcmp(valueStr, "alias", 5) ==0 ) // ==0 means equal { val=sys_getMachineAlias(); tslib_uitoa(val,returnStr); return true; } if ( memcmp(valueStr, "location", 8) ==0 ) { sys_getLocation(returnStr); return true; } // 2) time and date epi_getTime(&hh, &min, &ss); epi_getDate(&yy, &mon, &dd); epi_getToday(&dow, &minOfToday, &secOfToday); if ( memcmp(valueStr, "date ge", 7) ==0 ) { GetDateString(dd, mon, 0x20, yy, 0, 0, datebuf); for (int nn=0; nn<16; nn++) returnStr[nn] = datebuf[nn]; return true; } if ( memcmp(valueStr, "date us", 7) ==0 ) { GetDateString(dd, mon, 0x20, yy, 2, 1, datebuf); for (int nn=0; nn<16; nn++) returnStr[nn] = datebuf[nn]; return true; } if ( memcmp(valueStr, "time long", 9) ==0 ) // erstmal nur 24h system { GetTimeString(hh, min, ss, 0, 1, datebuf); for (int nn=0; nn<16; nn++) returnStr[nn] = datebuf[nn]; return true; } if ( memcmp(valueStr, "time shor", 9) ==0 ) { GetTimeString(hh, min, ss, 0, 0, datebuf); for (int nn=0; nn<16; nn++) returnStr[nn] = datebuf[nn]; return true; } if ( memcmp(valueStr, "wday eng shor", 13) ==0 ) { switch (dow) { case 1: returnStr[0]='m'; returnStr[1]='o'; break; case 2: returnStr[0]='t'; returnStr[1]='u'; break; case 3: returnStr[0]='w'; returnStr[1]='e'; break; case 4: returnStr[0]='t'; returnStr[1]='h'; break; case 5: returnStr[0]='f'; returnStr[1]='r'; break; case 6: returnStr[0]='s'; returnStr[1]='a'; break; case 7: returnStr[0]='s'; returnStr[1]='u'; break; default: returnStr[0]='-'; returnStr[1]='-'; break; } returnStr[2]=0; return true; } if ( memcmp(valueStr, "wday eng long", 13) ==0 ) { return true; } if ( memcmp(valueStr, "wday deu shor", 13) ==0 ) { return true; } if ( memcmp(valueStr, "wday deu long", 13) ==0 ) { return true; } // 3.) dynamics // char runProc_dynPrnVars[16][16]; // example: "vari","Dynamic02"; if ( memcmp(valueStr, "Dynamic", 7) ==0 ) { ddnum = ((valueStr[7]-0x30)*10 + (valueStr[8]-0x30)); if (ddnum>15) return false; prnRestoreDynamic( ddnum, returnStr); return true; } return false; } bool T_runProc::sys_translateKeys(void) { // 2) use key-value pairs from printer-Json-File and interpret them // store printer commands in chronologic order (will be printed in this order 0 1 2 3....) // to runProc_prnCmdSeq[512] and runProc_prnCmdPara[512]. nr of commands in total in "runProc_pointPrnCmd" // command 1=print text from textbuffer[nn] where nn is stored in runProc_prnCmdPara // number of key-value pairs: // runProc_nrOfLinesPrnFile // runProc_prnFile[LL].keyStr[] // runProc_prnFile[LL].valStr[] // header keys: "title", "project", "Version" - no action by now // Following keys are used: save as cmd: // text // drucke Text direkt -> t // styl // wie soll der Text aussehen -> s // feed // Papier bewegen -> f // vari // Werte aus Speicher drucken -> v // graf // drucke Log, QRcode oder Barcode -> g uint16_t pairNr=0, nn, pTxt; char keyCmd; char variStr[32]; runProc_prnSeqNr=0; runProc_pointPrnTxt=0; runProc_pointPrnCmd=0; for (nn=0; nn<128; nn++) runProc_prnTextSeq[nn].clear(); for (nn=0; nn<512; nn++) { runProc_prnCmdSeq[nn]=0; runProc_prnCmdPara [nn]=0; } runProc_pointPrnCmd=0; runProc_nrOfPrnDyns=0; // delete one time here do { keyCmd=sub_findKey(runProc_prnFile[pairNr].keyStr); switch(keyCmd) { case 't': pTxt=subStoreTicketText(runProc_prnFile[pairNr].valStr); runProc_prnCmdSeq[runProc_pointPrnCmd]=1; runProc_prnCmdPara[runProc_pointPrnCmd++]=pTxt; break; case 's': sub_changeStyle(runProc_prnFile[pairNr].valStr); break; case 'f': // new line nicht als Kommando senden sondern mit in den Textpuffer, geht schneller subFeedPaper(runProc_prnFile[pairNr].valStr); break; case 'v': memset(variStr,0,32); subGetVariStr(runProc_prnFile[pairNr].valStr, variStr); //subAppendNxtTxt(variStr); pTxt=subStoreTicketText(variStr); runProc_prnCmdSeq[runProc_pointPrnCmd]=1; runProc_prnCmdPara[runProc_pointPrnCmd++]=pTxt; break; case 'g': subPrintGrafics(runProc_prnFile[pairNr].valStr); break; // Header: case 'T': break; case 'P': break; case 'V': break; default: // irgendwas anderes, Kommentar oder Leerzeile. Tolerieren, einfach weiter break; } //qDebug()<<"runProc sys_translateKeys "<50) return 0; bool printerOK=prn_isUpAndReady(); // Printer Start =============================================== if (runProc_stepChainPrintDirect==1) { qDebug()<<"runProc start quick print"; if (printerOK) { runProc_stepChainPrintDirect=10; } else { // printer off-on for 100ms qDebug()<<"runProc quick print proff"; sendFDcmd_set(CMD2DC_PRINTERON,0,0, false,0,0,0); runProc_stepChainDelay=0; runProc_stepChainPrintDirect++; } } else if (runProc_stepChainPrintDirect==2) { if (++runProc_stepChainDelay>30) // 30 { qDebug()<<"runProc quick print pron"; sendFDcmd_set(CMD2DC_PRINTERON,0,0, true,0,0,0); runProc_stepChainDelay=0; runProc_stepChainPrintDirect++; } } else if (runProc_stepChainPrintDirect==3) { // waiting for printer getting ready if (++runProc_stepChainDelay>300) { // timeout 3s runProc_stepChainResult=2; // printer not ready runProc_stepChainPrintDirect= 99; // finish printerOK=prn_isUpAndReady(); // double, just for test qDebug()<<"runProc quick print TO pr not rdy"; } if (printerOK) { qDebug()<<"runProc quick print pr is ready"; runProc_stepChainPrintDirect=10; runProc_stepChainDelay=0; } } else // Printer Default Settings =============================================== if (runProc_stepChainPrintDirect==10) { // printer is ready now // default settings: if (++runProc_stepChainDelay>runProc_dirPrnCmdDelay) { qDebug()<<"runProc quick print send ini1"; prn_papSped=100; // 5...250 mm/s prn_density=25; // 0....(25)....50 prn_alignment='l'; // 'l', 'c', 'r' = left, center, right prn_orient=0; // 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) //prn_sendPrnSetup(prn_papSped, prn_density, prn_alignment, prn_orient); runProc_stepChainDelay=0; runProc_stepChainPrintDirect++; } } else if (runProc_stepChainPrintDirect==11) { if (++runProc_stepChainDelay>runProc_dirPrnCmdDelay) { qDebug()<<"runProc quick print send ini2"; prn_fontTyp=8; // kind of font 5...11 (0..22) prn_fontSiz=12; // 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge prn_width=0; // 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) prn_hei=0; // 0...7 = 1x...8x only 0,1,2,(3) make sense //sendFDcmd_set(CMD2DC_PRI_SETFONT, 0,0, prn_fontTyp, prn_fontSiz, prn_width, prn_hei); runProc_stepChainDelay=0; runProc_stepChainPrintDirect++; } } else if (runProc_stepChainPrintDirect==12) { if (++runProc_stepChainDelay>runProc_dirPrnCmdDelay) { qDebug()<<"runProc quick print send ini3"; prn_fontBold=0; // 0=off 1=on prn_fontInv=0; // 0=off 1=on prn_underLine=0; // 0=off 1=on //sendFDcmd_set(CMD2DC_PRI_SETLETTER, 0, 0, prn_fontBold, prn_fontInv, prn_underLine, 0); runProc_stepChainDelay=0; runProc_stepChainPrintDirect++; } } else if (runProc_stepChainPrintDirect==13) { if (++runProc_stepChainDelay>runProc_dirPrnCmdDelay) { if (printerOK) { qDebug()<<"runProc quick print step13: pr is rdy"; runProc_stepChainPrintDirect=20; runProc_TOcnt=0; } // else stay here if (++runProc_TOcnt>30) { qDebug()<<"runProc quick print step13: TO"; // printer is not ready after 3s, stop chain runProc_stepChainResult=2; // printer not ready runProc_stepChainPrintDirect= 99; // finish } runProc_pointPrnCmd=0; runProc_stepChainDelay=0; } } else // Print Saved Ticketdata =============================================== //static char runProc_prnTextSeq[128][1024]; //static uint8_t runProc_prnCmdSeq[512]; //static uint8_t runProc_prnCmdPara[512]; //static uint16_t runProc_pointPrnCmd; if (runProc_stepChainPrintDirect==20) { if (++runProc_stepChainDelay>runProc_dirPrnCmdDelay) { freeStak=check4freeFDstack(); // returns nr of free places in command stack if (freeStak<=1) { // cmd stack is full, wait 1s qDebug()<<"runProc quick print step20: cmdStack is full"; if (++runProc_TOcnt>30) { // still full after 3s qDebug()<<"runProc quick print step20 stop bec. 30xTO"; runProc_stepChainResult=3; // transmission disturbed runProc_stepChainPrintDirect= 99; // finish } else { runProc_stepChainPrintDirect++; runProc_stepChainDelay=0; } } else if (!printerOK) { if (++runProc_TOcnt>30) { // still not OK after 3s qDebug()<<"runProc quick print step20 stop bec. 30x pr not rdy"; runProc_stepChainResult=2; runProc_stepChainPrintDirect= 99; // finish } else { // wait a s runProc_stepChainPrintDirect++; runProc_stepChainDelay=0; } } else { // printer is OK, cmd-stack is OK, so send next command: runProc_TOcnt=0; nextCmd = runProc_prnCmdSeq[runProc_pointPrnCmd]; nextPara = runProc_prnCmdPara[runProc_pointPrnCmd]; if (nextCmd==0 || runProc_pointPrnCmd > 510) { // we're done qDebug()<<"runProc quick print step20: successful finished"; runProc_stepChainResult=1; runProc_stepChainPrintDirect=99; } else if (nextCmd==1 ) { // send text buffer qDebug()<<"runProc quick print step20 send TEXT " << nextCmd << " / " << nextPara; if (nextPara<128) prn_sendText(&runProc_prnTextSeq[nextPara]); qDebug()<100) { runProc_stepChainPrintDirect=20; runProc_stepChainDelay=0; } } else if (runProc_stepChainPrintDirect==99) { // do nothing } return 0; }