Table of Contents |
---|
...
The very step to avoid difficult integration times: unit test the external communication with ACE.
Code Block | ||||
---|---|---|---|---|
| ||||
// NAME....... Tutorial #1 // PURPOSE.... This code presents how to connect onto ACE and to use aceOut // // Hypothesis and optimizations: // Communication between ACE and acceptance device is IP // // PROJECT.... Wiki // REFERENCES. -- // // Copyright ©2005-2020 - 9164-4187 QUEBEC INC (“AMADIS”), All Rights Reserved // //--------------------------------------------------------- // Main //--------------------------------------------------------- int main(int argc, char** argv) { // Communication int port, length; char address[50]=""; // Get Communication parameters from ini file // These paramerters maybe wired inside the code for training purposes xgpiIniSetFilename("agnos.ini"); xgpiIniGetString("COM", "Address", 50, address, &length); xgpiIniGetNumeric("COM", "Port", &port); // Initialize ACE // Initialize generic communication interface assert(tcpInit(0) == TCP_NO_ERROR); // Create server and client assert(comtcpOpen(&gACEServerCOMTCP, TCP_SERVER, 0, port) == COM_NO_ERROR); assert(comtcpOpen(&gACEClientCOMTCP, TCP_CLIENT, address, 1979) == COM_NO_ERROR); // Set ACE with server and client aceInitializeCommunication(&gACEServerCOMTCP.com,&gACEClientCOMTCP.com); // Initialize running mode aceSetMode(pmSDK); // Set ACE option aceSetUIDisplay(bTRUE); // Trace into ACE aceOut("Training Session - BEGIN\n"); aceOut("Hello World!\n"); aceOut("Training Session - END\n"); return 0; } |
...
Code Block | ||
---|---|---|
| ||
// NAME....... Tutorial #7
// PURPOSE.... This code presents how to log APDU in batch mode
//
// Hypothesis and optimizations:
// Communication between ACE and acceptance device is IP
//
// PROJECT.... Wiki
// REFERENCES. --
//
// Copyright ©2005-2020 - 9164-4187 QUEBEC INC (“AMADIS”), All Rights Reserved
//
//---------------------------------------------------------
// Main
//---------------------------------------------------------
int main(int argc, char** argv)
{
// See previous examples to get a PAYMENT request from ACE
processRequest(buffer+1,len-1,pay);
char* parameters;
tStartingPoint sp = spSTART_A; // To initiate contactless transaction at preprocessing step
char line1[100]="",line2[100]="";
// Initialize GPI
// This is platform dependent. On Kizis AVT, this set PCSC readers' name from agnos.ini
gpiMain(0,¶meters);
// Load available kernels
enpConnectPaymentServices("./AGNOS/");
// Set contactless configurations
dtmInitializeFromFile("./AGNOS/",NULL,NULL,NULL,NULL,NULL,pay->mTransactionType,bFALSE);
// Initialization entry point
enpInitialize("","",bTRUE,bFALSE,bFALSE,pay);
gpiSetTechnoToDetect(TECHNO_CL_TYPE_EMV); // Right before polling, need to tell which techno to poll on
sprintf(line1,"PAY");
if(pay->mAmount)
{
sprintf(line2,"AMOUNT: %.2f",(*pay->mAmount)/100.0);
}
else
{
sprintf(line2,"--");
}
gpiSetPollingMessage(line1,line2,NULL);
// aceOut are to slow
// Let's use some testing signals the same way a TA would do
// Even if enpInitialize set signal = bTRUE, need to do more stuff
tSignal signal;
aceSetSignal(bTRUE); // Activate signal in ACE
aceSetDigitalSignal(bTRUE); // Use digital signal instead of legacy strings
aceGetSignal(&signal); // Get ACE signal services
pmwSetSignal(&signal); // Set AgnosMW accordingly
aceSetAPDULog(bFALSE); // Don't log APDU cmd/rsp in real-time
aceSetTrace(MAX_TRACE_DEPTH+1); // Log offline
enpExecutePaymentTransaction(sp,pay,out); // Call main entry point primitive to trigger a transaction
// Log all batched APDU now
aceLogAllBatchedAPDU();
// For the same price, send all tags to ACE
aceSendTag(pay);
// Clean session closing (will switch antenna off)
pay->mDataExchange.mError.mL1 = erL1OK; // Avoid display message within entry point
out->mUIReqOnRestartPresent = bFALSE; // Avoid display message within entry point
enpExecutePaymentTransaction(spNO_START,pay,out);
// Acknowledge ACE and sends several tags for receipt printing...
ackPayment(pay,out,((pay->mPOSEntryMode == EMV_CL_MODE) || (pay->mPOSEntryMode == MAG_CL_MODE)));
// UI stuff..
gpiClearScreen();
gpiDisplayMessageByID(gpi_true,currentLanguage,THANKS);
gpiSwitchLED(LED_1,gpi_false,0);
gpiSwitchLED(LED_2,gpi_false,0);
gpiSwitchLED(LED_3,gpi_false,0);
gpiSwitchLED(LED_4,gpi_false,0);
aceOut("Training Session - END\n");
return 0;
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
// NAME....... Tutorial #7
// PURPOSE.... This code presents how to log APDU in batch mode
//
// Hypothesis and optimizations:
// Communication between ACE and acceptance device is IP
//
// PROJECT.... Wiki
// REFERENCES. --
//
// Copyright ©2005-2020 - 9164-4187 QUEBEC INC (“AMADIS”), All Rights Reserved
//
//---------------------------------------------------------
// Main
//---------------------------------------------------------
int main(int argc, char** argv)
{
// See previous examples to get a PAYMENT request from ACE
processRequest(buffer+1,len-1,pay);
char* parameters;
tStartingPoint sp = spSTART_A; // To initiate contactless transaction at preprocessing step
char line1[100]="",line2[100]="";
// Initialize GPI
// This is platform dependent. On Kizis AVT, this set PCSC readers' name from agnos.ini
gpiMain(0,¶meters);
// Load available kernels
enpConnectPaymentServices("./AGNOS/");
// Set contactless configurations
dtmInitializeFromFile("./AGNOS/",NULL,NULL,NULL,NULL,NULL,pay->mTransactionType,bFALSE);
// Initialization entry point
enpInitialize("","",bFALSE,bFALSE,bFALSE,pay); // No more signal managed now
tTerminalContext *terminalCtx = NULL;
tByte technoToDetect = TECHNO_CL_TYPE_EMV;
tGPIError gpiError = 0;
terminalCtx = (tTerminalContext*)dtmGetData(TERMINAL_CTX);
if(terminalCtx->mMagstripe)
{
technoToDetect |= TECHNO_MAGSTRIPE;
}
if(terminalCtx->mEMVContact)
{
technoToDetect |= TECHNO_CONTACT;
}
gpiSetTechnoToDetect(technoToDetect);
sprintf(line1,"PAY");
if(pay->mAmount)
{
sprintf(line2,"AMOUNT: %.2f",(*pay->mAmount)/100.0);
}
else
{
sprintf(line2,"--");
}
gpiDisplayMessage(gpi_true,line1);
gpiDisplayMessage(gpi_false,line2);
gpiError = gpiPolling("",5); // timeout set to 5 seconds
sprintf(tmp,"GPI ERROR: 0x%.4X\n",gpiError);
aceOut(tmp);
if(scrINTERRUPTED == gpiError)
{
sprintf(tmp,"TRANSACTION INTERRUPTED\n");
aceOut(tmp);
}
else if(polTIMEOUT == gpiError)
{
sprintf(tmp,"No Tap\n");
aceOut(tmp);
}
else
{
sprintf(tmp,"CARD DETECTED FROM L3\n");
aceOut(tmp);
enpSkipPollingOnNextStartB(gpiError);
enpExecutePaymentTransaction(sp,pay,out); // Call main entry point primitive to trigger a transaction
if (ocONLINE_REQUEST == out->mOutCome)
{
gpiDisplayMessage(gpi_true,"ONLINE");
length = 0;
pmwGetEMVData( pay->mSession,(tByte*)"\x9F\x02\x95\x9F\x26\x9F\x27",7,
pay->mDataExchange.mDataRecord.mStream,&pay->mDataExchange.mDataRecord.mLength);
// For example, use ACE to emulate online auth.
aceSendContactlessAuthorization(pay,bFALSE);
if (TC == pay->mCID)
{
gpiDisplayMessage(gpi_true,"APPROVED");
}
else
{
gpiDisplayMessage(gpi_true,"DECLINED");
}
}
else if (ocAPPROVED == out->mOutCome)
{
gpiDisplayMessage(gpi_true,"APPROVED");
}
else
{
gpiDisplayMessage(gpi_true,"DECLINED");
}
}
// Clean session closing (will switch antenna off)
pay->mDataExchange.mError.mL1 = erL1OK; // Avoid display message within entry point
out->mUIReqOnRestartPresent = bFALSE; // Avoid display message within entry point
enpExecutePaymentTransaction(spNO_START,pay,out);
// Acknowledge ACE and sends several tags for receipt printing...
ackPayment(pay,out,((pay->mPOSEntryMode == EMV_CL_MODE) || (pay->mPOSEntryMode == MAG_CL_MODE)));
// UI stuff..
gpiClearScreen();
gpiDisplayMessageByID(gpi_true,currentLanguage,THANKS);
gpiSwitchLED(LED_1,gpi_false,0);
gpiSwitchLED(LED_2,gpi_false,0);
gpiSwitchLED(LED_3,gpi_false,0);
gpiSwitchLED(LED_4,gpi_false,0);
aceOut("Training Session - END\n");
return 0;
} |
Tutorial #9: integrate Data Exchange for contactless
Code Block | ||
---|---|---|
| ||
// NAME....... Tutorial #7
// PURPOSE.... This code presents how to log APDU in batch mode
//
// Hypothesis and optimizations:
// Communication between ACE and acceptance device is IP
//
// PROJECT.... Wiki
// REFERENCES. --
//
// Copyright ©2005-2020 - 9164-4187 QUEBEC INC (“AMADIS”), All Rights Reserved
//
//---------------------------------------------------------
// Main
//---------------------------------------------------------
int main(int argc, char** argv)
{ // See previous examples to get a PAYMENT request from ACE
processRequest(buffer+1,len-1,pay);
char* parameters;
tStartingPoint sp = spSTART_A; // To initiate contactless transaction at preprocessing step
char line1[100]="",line2[100]="";
// Initialize GPI
// This is platform dependent. On Kizis AVT, this set PCSC readers' name from agnos.ini
gpiMain(0,¶meters);
// Load available kernels
enpConnectPaymentServices("./AGNOS/");
// Set contactless configurations
dtmInitializeFromFile("./AGNOS/",NULL,NULL,NULL,NULL,NULL,pay->mTransactionType,bFALSE);
// Initialization entry point
enpInitialize("","",bFALSE,bFALSE,bFALSE,pay); // No more signal managed now
tTerminalContext *terminalCtx = NULL;
tByte technoToDetect = TECHNO_CL_TYPE_EMV;
tGPIError gpiError = 0;
terminalCtx = (tTerminalContext*)dtmGetData(TERMINAL_CTX);
if(terminalCtx->mMagstripe)
{
technoToDetect |= TECHNO_MAGSTRIPE;
}
if(terminalCtx->mEMVContact)
{
technoToDetect |= TECHNO_CONTACT;
}
gpiSetTechnoToDetect(technoToDetect);
sprintf(line1,"PAY");
if(pay->mAmount)
{
sprintf(line2,"AMOUNT: %.2f",(*pay->mAmount)/100.0);
}
else
{
sprintf(line2,"--");
}
gpiDisplayMessage(gpi_true,line1);
gpiDisplayMessage(gpi_false,line2);
gpiError = gpiPolling("",5); // timeout set to 5 seconds
sprintf(tmp,"GPI ERROR: 0x%.4X\n",gpiError);
aceOut(tmp);
if(scrINTERRUPTED == gpiError)
{
sprintf(tmp,"TRANSACTION INTERRUPTED\n");
aceOut(tmp);
}
else if(polTIMEOUT == gpiError)
{
sprintf(tmp,"No Tap\n");
aceOut(tmp);
}
else
{
sprintf(tmp,"CARD DETECTED FROM L3\n");
aceOut(tmp);
// Use DF12 - TAGS to READ - inside contactless combination
// DF12015A will trigger the data exchange mechanism when tag 5A will be found
pay->mDataExchange.mCallback = &myDEProcess;
pay->mDataExchange.mDEList = &gDEListCtx;
enpSkipPollingOnNextStartB(gpiError);
enpExecutePaymentTransaction(sp,pay,out); // Call main entry point primitive to trigger a transaction
if (ocONLINE_REQUEST == out->mOutCome)
{
gpiDisplayMessage(gpi_true,"ONLINE");
length = 0;
pmwGetEMVData( pay->mSession,(tByte*)"\x9F\x02\x95\x9F\x26\x9F\x27",7,
pay->mDataExchange.mDataRecord.mStream,&pay->mDataExchange.mDataRecord.mLength);
// For example, use ACE to emulate online auth.
aceSendContactlessAuthorization(pay,bFALSE);
if (TC == pay->mCID)
{
gpiDisplayMessage(gpi_true,"APPROVED");
}
else
{
gpiDisplayMessage(gpi_true,"DECLINED");
}
}
else if (ocAPPROVED == out->mOutCome)
{
gpiDisplayMessage(gpi_true,"APPROVED");
}
else
{
gpiDisplayMessage(gpi_true,"DECLINED");
}
}
// Clean session closing (will switch antenna off)
pay->mDataExchange.mError.mL1 = erL1OK; // Avoid display message within entry point
out->mUIReqOnRestartPresent = bFALSE; // Avoid display message within entry point
enpExecutePaymentTransaction(spNO_START,pay,out);
// Acknowledge ACE and sends several tags for receipt printing...
ackPayment(pay,out,((pay->mPOSEntryMode == EMV_CL_MODE) || (pay->mPOSEntryMode == MAG_CL_MODE)));
// UI stuff..
gpiClearScreen();
gpiDisplayMessageByID(gpi_true,currentLanguage,THANKS);
gpiSwitchLED(LED_1,gpi_false,0);
gpiSwitchLED(LED_2,gpi_false,0);
gpiSwitchLED(LED_3,gpi_false,0);
gpiSwitchLED(LED_4,gpi_false,0);
aceOut("Training Session - END\n");
return 0; |