Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

...

The very step to avoid difficult integration times: unit test the external communication with ACE.

View file
nametutorial#1

Code Block
breakoutModewide
languagec
int main(int argc, char** argv)
{
  // Communication
  int port, length;
  char address[50]="";

  // Get communication parameters from ini file
  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);

  // Device side is server fro ACE
  assert(comtcpOpen(&gACEServerCOMTCP, TCP_SERVER, 0, port) == COM_NO_ERROR);
  // Device side is also an ACE client
  assert(comtcpOpen(&gACEClientCOMTCP, TCP_CLIENT, address, 1979) == COM_NO_ERROR);

  aceInitializeCommunication(&gACEServerCOMTCP.com,&gACEClientCOMTCP.com);

  // Initialize running mode
  aceSetMode(pmSDK);
	
  // Set ACE option
  aceSetUIDisplay(bTRUE);

  // Tutorial
  aceOut("Training Session - BEGIN\n");
  aceOut("Hello World!\n");
  aceOut("Training Session - END\n");

	return 0;
}

...

Code Block
breakoutModewide
languagec
  void processRequest(tByte* request, tWord requestLen, tPaymentContext* ctx)
{
	tByte date[4], time[3], datetime[6];
	cursor_t cursorRequest;
	byte_t *value;

	static tByte TRD[500] = "";
	static tWord TRDLength = 0;

	if(!requestLen || !request)
		return;

	gpiMemCpy(TRD,request,requestLen);
	TRDLength = requestLen;


	// Parse TLV stream
	if(tlvInitCursor(request,requestLen,requestLen,&cursorRequest)==TLV_NO_ERROR)
	{
		// Map tags to tPaymentContext structure
		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9C,1,&cursorRequest)==TLV_NO_ERROR)
		{
			value = tlvGetValue(&cursorRequest);
			if(value)
			{
				if(*value==0x00)		ctx->mTransactionType = ttPURCHASE;
				else if(*value==0x01)	ctx->mTransactionType = ttCASH;
				else if(*value==0x030x09)	ctx->mTransactionType = ttPREttWITH_AUTHORIZATIONCASHBACK;
// Required by Interac Flash L2 certification!
				else if(*value==0x09)					ctx->mTransactionType = ttWITH_CASHBACKttUNDEFINED;
			}
			else
if(*value==0x20)				ctx->mTransactionType = ttREFUNDttUNDEFINED;
		}
		else if(*value==0x12)	ctx->mTransactionType = ttMANUAL_CASH;
				else					ctx->mTransactionType = ttUNDEFINED;
			}
			else
				ctx->mTransactionType = ttUNDEFINED;
		}
		// as per new // as per new GTBI as of december 2014: ctx->mTransactionType is set at initialization time from agnos.ini
		//else
			//ctx->mTransactionType = ttPURCHASE;

		if(ctx->mTransactionType == ttWITH_CASHBACK)
		{
			tlvResetCursor(&cursorRequest);
			if(tlvFindTag(0x9F02,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
			{
				ctx->mAmount = NULL;
				ctx->mCashBack = NULL;
			}
			else
			{
				if(tlvGetLength(&cursorRequest))
					convertBCDToAmount(ctx->mAmount,tlvGetValue(&cursorRequest),6);
				else
					ctx->mAmount = NULL;

				if(tlvFindTag(0x9F03,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
					ctx->mCashBack = NULL;
				else
				{
					if(tlvGetLength(&cursorRequest))
						convertBCDToAmount(ctx->mCashBack,tlvGetValue(&cursorRequest),6);
					else
						ctx->mCashBack = NULL;
				}
			}
		}
		else
		{	// ttPURCHASE or ttCASH or ttMANUALCASH or ttREFUND or ttDEPOSIT or dummy value
			tlvResetCursor(&cursorRequest);
			if(tlvFindTag(0x9F02,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
			{
				ctx->mAmount = NULL;
				ctx->mCashBack = NULL;
			}
			else
			{
				if(tlvGetLength(&cursorRequest))
				{
					convertBCDToAmount(ctx->mAmount,tlvGetValue(&cursorRequest),6);

					tlvResetCursor(&cursorRequest);
					if(tlvFindTag(0x9F03,1,&cursorRequest)==TLV_ERR_TAG_NOT_FOUND)
						ctx->mCashBack = NULL;
					else
					{
						if(tlvGetLength(&cursorRequest))
							convertBCDToAmount(ctx->mCashBack,tlvGetValue(&cursorRequest),6);
						else
							ctx->mCashBack = NULL;
					}
				}
				else
				{
					ctx->mAmount = NULL;
					ctx->mCashBack = NULL;
				}
			}
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0xDF04,1,&cursorRequest)==TLV_NO_ERROR)
			dtxSetBalanceBeforeGenAC(&ctx->mDataExchange,tlvGetValue(&cursorRequest));

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0xDF05,1,&cursorRequest)==TLV_NO_ERROR)
			dtxSetBalanceAfterGenAC(&ctx->mDataExchange,tlvGetValue(&cursorRequest));

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9F7C,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
				gpiMemCpy(ctx->mMerchantCustomData,tlvGetValue(&cursorRequest),20);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9F53,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
				ctx->mTransactionCategoryCode = *(tlvGetValue(&cursorRequest));
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9A,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
			{
				gpiMemCpy(ctx->mTransactionDate,tlvGetValue(&cursorRequest),3);

				// Mantis 0000142: Set date and time from ACE
				// Synchronize system's date from ACE
				datetime[0] = bcdToDecimal(ctx->mTransactionDate[0]);
				datetime[1] = bcdToDecimal(ctx->mTransactionDate[1]);
				datetime[2] = bcdToDecimal(ctx->mTransactionDate[2]);
				gpiGetTime(time);
				gpiMemCpy(datetime+3,time,3);
				gpiSetDateTime(datetime);
			}
			else
			{
				gpiGetDate(date);
				ctx->mTransactionDate[0] = toNumeric(date[1]);
				ctx->mTransactionDate[1] = toNumeric(date[2]);
				ctx->mTransactionDate[2] = toNumeric(date[3]);
			}
		}
		else
		{
			gpiGetDate(date);
			ctx->mTransactionDate[0] = toNumeric(date[1]);
			ctx->mTransactionDate[1] = toNumeric(date[2]);
			ctx->mTransactionDate[2] = toNumeric(date[3]);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x9F21,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
			{
				gpiMemCpy(ctx->mTransactionTime,tlvGetValue(&cursorRequest),3);

				// Mantis 0000142: Set date and tiem from ACE
				// Synchronize system's time from ACE
				gpiGetDate(date);
				gpiMemCpy(datetime,date+1,3);
				datetime[3] = bcdToDecimal(ctx->mTransactionTime[0]);
				datetime[4] = bcdToDecimal(ctx->mTransactionTime[1]);
				datetime[5] = bcdToDecimal(ctx->mTransactionTime[2]);
				gpiSetDateTime(datetime);
			}
			else
			{
				gpiGetTime(time);
				ctx->mTransactionTime[0] = toNumeric(time[0]);
				ctx->mTransactionTime[1] = toNumeric(time[1]);
				ctx->mTransactionTime[2] = toNumeric(time[2]);
			}
		}
		else
		{
			gpiGetTime(time);
			ctx->mTransactionTime[0] = toNumeric(time[0]);
			ctx->mTransactionTime[1] = toNumeric(time[1]);
			ctx->mTransactionTime[2] = toNumeric(time[2]);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x5F2A,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
				gpiMemCpy(ctx->mTransactionCurrencyCode,tlvGetValue(&cursorRequest),2);
		}

		tlvResetCursor(&cursorRequest);
		if(tlvFindTag(0x5F36,1,&cursorRequest)==TLV_NO_ERROR)
		{
			if(tlvGetValue(&cursorRequest))
					ctx->mTransactionCurrencyExponent = *(tlvGetValue(&cursorRequest));
		}
	}
}

//---------------------------------------------------------
//            Main
//---------------------------------------------------------
//  Main function:
//		- Initialize the platform
//		- Wait for payment trigger
//		- Initialize the data model
//		- Perform a payment
//
//  Visibility: Public
//  Hypothesis: --
//  Reference: --
//
int main(int argc, char** argv)
{
  // Do all initializations    
  // Wait for inbound sale request
  // See previous tutorials

  // Contexts are empty
  outPaymentContext(pay);
  outOutcomeParameter(out);

  // Fill-up contextes from ACE request
  processRequest(buffer+1,len-1,pay);

  // Contexts are ready
  outPaymentContext(pay);
  outOutcomeParameter(out);

  // Acknomledge payment request
  aceSendResponse((unsigned char*)"\x30\x30",2);

  gpiDisplayMessageByID(gpi_true,currentLanguage+1,THANKS);

  aceOut("Training Session - END\n");

	return 0;
}

...