Versions Compared

Key

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

...

API _Version _Revision

...

Description

...

_OLA _version 2.1.6 _revision 23819

...

Open L2 API

...

ola

...

See ola.h

...

#include

...

Code Block
languagec
#include "ola_tags_dictionary.h"
#include "ola_emv.h" /// Generic EMV API
#include "ola_publickey.h" /// Generic Public Key configuration API
#include "ola_contactless.h" /// Generic Contacless Processing API
#include "ola_contact.h" /// Generic Contact Processing API

...

#define

...

Code Block
languagec
#define OLA_API_VERSION "2.1.6"

...

logf_function

...

Code Block
languagec
typedef void (*logf_function)(char* str);

...

ola_get_api_version

...

Code Block
languagec
const char *ola_get_api_version(void);

...

ola_get_implementation_version

...

Code Block
languagec
const char *ola_get_implementation_version(void);

...

ola_initialize_at_start_up

...

Code Block
languagec
tOLAError ola_initialize_at_start_up(uint8_t *tlv, uint16_t tlvLength);

...

ola_set_trace_function

...

Code Block
languagec
void ola_set_trace_function(logf_function fct);

...

ola_emv

...

See ola_emv.h

...

#include

...

Code Block
languagec
#include <stdint.h>

...

tOLAError

...

Code Block
languagec
typedef enum
{
	OLA_OK,
	OLA_CARD_MUTE,
	OLA_CARD_BLOCKED,
	OLA_MAX_REACHED,
	OLA_NO_CANDIDATE,
	OLA_CONTACT_NEW_SELECTION,
	OLA_CONTACT_SELECTION_ERROR,
	OLA_CONDITIONS_NOT_SATISFIED,
	OLA_ACCEPTED,
	OLA_NOT_ACCEPTED,
	OLA_OFFLINE_ACCEPTED,
	OLA_OFFLINE_DECLINED,
	OLA_GO_ONLINE,
	OLA_DECLINED,
	OLA_MISSING_DATA,
	OLA_PINPAD_ERROR,
	OLA_PARAM_ERROR,
	OLA_NOT_IMPLEMENTED,
	OLA_ERROR,
	OLA_CARD_ERROR,
	OLA_CANCEL,
	OLA_PUBLIC_KEY_OK,
	OLA_PUBLIC_KEY_MISSING,
	OLA_PUBLIC_KEY_MAX_REACHED,
	OLA_PUBLIC_KEY_END,
	OLA_PUBLIC_KEY_ERROR,
	OLA_CARD_REMOVED
} tOLAError;

...

tOlaEMVCoCVM

...

Code Block
languagec
typedef enum
{
    cvmNone,
    cvmNoCvm,
    cvmSignature,
    cvmOnlinePin,
    cvmOnlinePin_Signature,
    cvmOfflinePinPlaintext,
    cvmOfflinePinPlaintext_Signature,
    cvmOfflinePinCiphered,
    cvmOfflinePinCiphered_Signature
} tOlaEMVCoCVM;

...

ola_emv_set_tag

...

Code Block
languagec
tOLAError ola_emv_set_tag(
	uint32_t tag,
    uint8_t *value,
    uint16_t length
);

...

ola_emv_get_tag

...

Code Block
tOLAError ola_emv_get_tag(
	uint32_t tag,
    uint8_t *value,
    uint16_t *length
);

...

ola_emv_get_cvm_results

...

Code Block
languagec
tOLAError ola_emv_get_cvm_results(
	tOlaEMVCoCVM *cvm
);

...

ola_contact

...

See ola_contact.h

...

#include

...

Code Block
languagec
#include "ola_emv.h"
#include <stdint.h>

...

tOlaModeContactTransaction

...

Code Block
languagec
typedef enum
{
    metUndef = 0,
    metFull,
    metExtractPAN,
    metUnknown
} tOlaModeContactTransaction;

...

ola_contact_flush_aid_supported

...

Code Block
languagec
void ola_contact_flush_aid_supported(void);

...

ola_contact_answer_to_reset

...

Code Block
languagec
tOLAError ola_contact_answer_to_reset(const char* reader);

...

ola_contact_add_aid_supported

...

Code Block
tOLAError  ola_contact_add_aid_supported(
		const uint8_t *aid,
	    uint8_t aidLength,
		int partial
);

...

ola_contact_build_candidate_list

...

Code Block
tOLAError ola_contact_build_candidate_list(
		uint8_t *nb_candidates,
	    int *pse
);

...

ola_contact_get_tag_from_candidate

...

Code Block
languagec
tOLAError ola_contact_get_tag_from_candidate(
		uint8_t candidate,
	    uint32_t tag,
		uint8_t *value,
	    uint16_t *length
);

...

ola_contact_final_select_candidate

...

Code Block
languagec
tOLAError ola_contact_final_select_candidate(uint8_t candidate);

...

ola_contact_initiate_transaction

...

Code Block
languagec
tOLAError ola_contact_initiate_transaction(
		tOlaModeContactTransaction mode
);

...

ola_contact_complete_transaction

...

Code Block
languagec
tOLAError ola_contact_complete_transaction(
		const uint8_t *authorResponseCode,
	    const uint8_t *issuerAuthenticationData,
	    uint8_t issuerAuthenticationData_length
);

...

ola_contact_clean

...

Code Block
languagec
void  ola_contact_clean(void);

...

ola_contactless

...

See ola_contactless.h

...

#include

...

Code Block
languagec
#include "ola_emv.h"
#include <stdint.h>

...

#define

...

Code Block
#define OLA_KERNEL_ID_MASTERCARD                    2
#define OLA_KERNEL_ID_VISA                          3
#define OLA_KERNEL_ID_AMEX                          4
#define OLA_KERNEL_ID_JCB                           5
#define OLA_KERNEL_ID_DISCOVER                      6
#define OLA_KERNEL_ID_CUP                           7

#define OLA_MSD_ID_APPROVED                         0x03
#define OLA_MSD_ID_NOT_AUTHORISED                   0x07
#define OLA_MSD_ID_PLEASE_INSERT_OR_SWIPE_CARD      0x18
#define OLA_MSD_ID_AUTHORISING_PLEASE_WAIT          0x1B
#define OLA_MSD_ID_INSERT_SWIPE_OR_TRY_ANOTHER_CARD 0x1C
#define OLA_MSD_ID_SEE_PHONE_FOR_INSTRUCTIONS       0x20

...

tOlaContactlessTransactionStep

...

Code Block
languagec
typedef enum
{
	ctsNone,
	ctsPreprocess,
	ctsBuildCandidate,
	ctsFinalSelect,
	ctsActivate
} tOlaContactlessTransactionStep;

...

tOlaOutcome

...

Code Block
languagec
typedef enum
{
	outcNone,
	outcSelectNext,
	outcTryAgain,
	outcApproved,
	outcDeclined,
	outcOnlineRequest,
	outcTryAnotherInterface,
	outcEndApplication
} tOlaOutcome;

...

tOlaStartPoint

...

Code Block
languagec
typedef enum
{
	spNoStart,
	spStartA,
	spStartB,
	spStartC,
	spStartD,
} tOlaStartPoint;

...

tOlaOnlineResponseData

...

Code Block
languagec
typedef enum
{
	ordNone,
	ordEmv,
	ordAny
} tOlaOnlineResponseData;

...

tOlaAlternateInterfacePreference

...

Code Block
languagec
typedef enum
{
	aipNone,
	aipContactChip,
	aipMagneticStripe
} tOlaAlternateInterfacePreference;

...

tOlaCVMethodContactless

...

Code Block
languagec
typedef enum
{
	cvmclNone,
	cvmclNoCvm,
	cvmclSignature,
	cvmclOnlinePin,
	cvmclConfirmationCodeVerified
} tOlaCVMethodContactless;

...

tOlaStatus

...

Code Block
languagec
typedef enum
{
	staNone,
	staNotReady,
	staIdle,
	staReadyToRead,
	staProcessing,
	staCardReadSuccessfully,
	staProcessingError
} tOlaStatus;

...

tOlaValueQualifier

...

Code Block
languagec
typedef enum
{
	vqNone,
	vqAmount,
	vqBalance
} tOlaValueQualifier;

...

tOlaOutcomeParameter

...

Code Block
languagec
typedef struct
{
	tOlaOutcome outCome;
	tOlaStartPoint startingPoint;
	tOlaOnlineResponseData onlineResponseData;
	tOlaCVMethodContactless cvm;
	int UIReqOnOutcomePresent;
	int UIReqOnRestartPresent;
	int receipt;
	int dataRecordPresent;
	int discretionaryDataPresent;
	tOlaAlternateInterfacePreference alternateInterfacePreference;
	uint32_t fieldOffReq;
	uint32_t removalTimeout;
} tOlaOutcomeParameter;

...

tOlaUIRequest

...

Code Block
languagec
typedef struct
{
	uint8_t messageIdentifier;
	tOlaStatus status;
	uint32_t holdTime;
	uint8_t languagePreference[8];  // List of languages, ISO 639-1 representation
	tOlaValueQualifier valueQualifier;
	uint8_t value[6];               // BCD
	uint8_t currencyCode[2];        // Numeric ISO 4217
} tOlaUIRequest;

...

ola_contactless_flush_aid_supported

...

Code Block
void ola_contactless_flush_aid_supported(void);

...

ola_contactless_add_aid_supported

...

Code Block
languagec
tOLAError ola_contactless_add_aid_supported(
        const uint8_t *aid,
        uint8_t aidLength,
        int partial,
        uint8_t kernelId,
        uint8_t *tlv,
        uint16_t tlvLength
);

...

ola_contactless_add_drl_supported

...

Code Block
languagec
uint16_t ola_contactless_add_drl_supported(
        const uint8_t *programId,
        uint8_t programIdLength,
        const uint8_t *transactionLimit,
        const uint8_t *floorLimit,
        const uint8_t *CVMLimit,
        int statusCheck,
        int isZeroAllowed,
        uint8_t kernelId
);

...

ola_contactless_commit_supported_aids

...

Code Block
void ola_contactless_commit_supported_aids(void);

...

ola_contactless_build_candidate_list

...

Code Block
uint16_t ola_contactless_build_candidate_list(
        uint8_t *nb_candidates
);

...

ola_contactless_get_tag_from_candidate

...

Code Block
languagec
uint16_t ola_contactless_get_tag_from_candidate(
        uint8_t candidate,
        uint32_t tag,
        uint8_t *value,
        uint16_t *length
);

...

ola_contactless_final_select_candidate

...

Code Block
languagec
tOLAError ola_contactless_final_select_candidate(
        uint8_t candidate,
        uint8_t *kernelId
);

...

ola_contactless_get_card_preferred_language

...

Code Block
tOLAError ola_contactless_get_card_preferred_language(
        char *language
);

...

ola_contactless_preprocess

...

Code Block
languagec
tOLAError ola_contactless_preprocess(void);

...

ola_contactless_do_transaction

...

Code Block
languagec
tOLAError ola_contactless_do_transaction(void);

...

ola_contactless_clean

...

Code Block
languagec
void  ola_contactless_clean(void);

...

ola_contactless_get_outcome

...

Code Block
tOLAError ola_contactless_get_outcome(
        tOlaOutcomeParameter *outcome
);

...

ola_contactless_get_UI_request_upon_outcome

...

Code Block
languagec
tOLAError ola_contactless_get_UI_request_upon_outcome(
        tOlaUIRequest *uiRequest
);

...

ola_contactless_get_UI_request_restart

...

Code Block
languagec
tOLAError ola_contactless_get_UI_request_restart(
        tOlaUIRequest *uiRequest
);

...

ola_publickey

...

See ola_publickey.h

...

#include

...

Code Block
languagec
#include "ola.h"
#include <stdint.h>

...

tOlaPubKey

...

Code Block
languagec
typedef struct
{
    uint8_t rid[5];
    uint8_t idx[1];
    uint8_t modulusLen;
    uint8_t modulusValue[248];
    uint8_t exponentLen;
    uint8_t exponentValue[3];
    uint8_t expirDate[3];
} tOlaPubKey;

...

ola_pubkey_flush

...

Code Block
void ola_pubkey_flush(void);

...

ola_pubkey_add

...

Code Block
tOLAError ola_pubkey_add(
        const tOlaPubKey *key,
        const uint8_t *checksum
);

...

ola_pubkey_find

...

Code Block
tOLAError ola_pubkey_find(
		tOlaPubKey *key,
        uint8_t *checksum
);

...

ola_pubkey_get_next_id

...

Code Block
tOLAError ola_pubkey_get_next_id(
        uint8_t *idx,
        uint8_t *rid,
        int start
);

...

ola_pubkey_commit

...

Code Block
tOLAError ola_pubkey_commit(void);

...

ola_terminal

...

See ola_terminal.h

...

// Deprecated

...

ola_tags_dictionary

...

See ola_tags_dictionary.h

...

#define

...

Code Block
#define TAG_TAC_DEFAULT                                 			0xDF1E
#define TAG_TAC_DENIAL                                  			0xDF1F
#define TAG_TAC_ONLINE                                  			0xDF20

#define TAG_READER_CONTACTLESS_FLOOR_LIMIT_PREPROCESSING            0xDF09
#define TAG_READER_CONTACTLESS_FLOOR_LIMIT       					0xDF8123 // Be careful, tag managed as 9F1B by Nexo!

#define TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM_PREPROCESSING    0xDF08
#define TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM        			0xDF8124

#define TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT_PREPROCESSING     0xDF0B
#define TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT       			0xDF8126

#define TAG_THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION 			0xDF21
#define TAG_MAXIMUM_TARGET_PERCENTAGE_FOR_BIASED_RANDOM_SELECTION 	0xDF1C
#define TAG_TARGET_PERCENTAGE_FOR_RANDOM_SELECTION      			0xDF1D

#define TAG_MESSAGE_HOLD_TIME                       				0xDF812D

// Contact
#define TAG_APPLICATION_PROFILE_SETTINGS                			0xDF27
#define TAG_DEFAULT_DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST	0xDF8F1A
#define TAG_DEFAULT_TRANSACTION_CERTIFICATE_DATA_OBJECT_LIST		0xDF8F08

// Kernel 2
#define TAG_BALANCE_READ_AFTER_GEN_AC                   			0xDF8105
#define TAG_BALANCE_READ_BEFORE_GEN_AC                  			0xDF8104
#define TAG_CARD_DATA_INPUT_CAPABILITIES            				0xDF8117
#define TAG_CVM_CAPABILITY_CVM_REQUIRED            					0xDF8118
#define TAG_CVM_CAPABILITY_NO_CVM_REQUIRED          				0xDF8119
#define TAG_DEFAULT_UDOL                            				0xDF811A
#define TAG_KERNEL_2_CONFIGURATION                  				0xDF811B
#define TAG_MAX_LIFETIME_TORN_TRANSACTION           				0xDF811C
#define TAG_MAX_NUMBER_TORN_TRANSACTION             				0xDF811D
#define TAG_MAGSTRIPE_CVM_CAPABILITY_CVM_REQUIRED   				0xDF811E
#define TAG_SECURITY_CAPABILITIES                   				0xDF811F
#define TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_DEVICE_CVM   		0xDF8125
#define TAG_MAGSTRIPE_CVM_CAPABILITY_NO_CVM_REQUIRED				0xDF812C
#define TAG_HOLD_TIME_VALUE       									0xDF8130
#define TAG_MIN_RELAY_RESISTANCE_GRACE_PERIOD       				0xDF8132
#define TAG_MAX_RELAY_RESISTANCE_GRACE_PERIOD       				0xDF8133
#define TAG_RELAY_RESISTANCE_ACCURACY_THRESHOLD     				0xDF8136
#define TAG_RELAY_RESISTANCE_TRANSMISSION_TIME_MISMATCH_THRESHOLD 	0xDF8137

...

ola_implem

...

See ola_implem.h

...

ola_contact_implem_t

...

Code Block
typedef struct {
	void (*flush_aid_supported)(void);
	tOLAError (*answer_to_reset)(const char* reader);
	tOLAError (*add_aid_supported)(const uint8_t *aid, uint8_t aidLength, int partial);
	tOLAError (*build_candidate_list)(uint8_t *nb_candidates, int *pse);
	tOLAError (*get_tag_from_candidate)(uint8_t candidate, uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*final_select_candidate)(uint8_t candidate);
	tOLAError (*initiate_transaction)(tOlaModeContactTransaction mode);
	tOLAError (*complete_transaction)(
			const uint8_t *authorResponseCode,
			const uint8_t *issuerAuthenticationData,
			uint8_t issuerAuthenticationData_length);
	void  (*clean)(void);
} ola_contact_implem_t;

...

ola_contactless_implem_t

...

Code Block
typedef struct {
	void (*flush_aid_supported)(void);
	tOLAError (*add_aid_supported)(
			const uint8_t *aid,
			uint8_t aidLength, int partial,
			uint8_t kernelId,
			const uint8_t *tlv,
			uint16_t tlvLength);
	uint16_t (*add_drl_supported)(
			const uint8_t *programId,
			uint8_t programIdLength,
			const uint8_t *transactionLimit,
			const uint8_t *floorLimit,
			const uint8_t *CVMLimit,
			int statusCheck,
			int isZeroAllowed,
			uint8_t kernelId);
	void (*commit_supported_aids)(void);
	uint16_t (*build_candidate_list)(uint8_t *nb_candidates);
	uint16_t (*get_tag_from_candidate)(uint8_t candidate, uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*final_select_candidate)(uint8_t candidate, uint8_t *kernelId);
	tOLAError (*get_card_preferred_language)(char *language);
	tOLAError (*preprocess)(void);
	tOLAError (*do_transaction)(void);
	void (*clean)(void);
	tOLAError (*get_outcome)(tOlaOutcomeParameter *outcome);
	tOLAError (*get_UI_request_upon_outcome)(tOlaUIRequest *uiRequest);
	tOLAError (*get_UI_request_restart)(tOlaUIRequest *uiRequest);
} ola_contactless_implem_t;

...

ola_emv_implem_t

...

Code Block
languagec
typedef struct {
	tOLAError (*set_tag)(uint32_t tag, uint8_t *value, uint16_t length);
	tOLAError (*get_tag)(uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*get_cvm_results)(tOlaEMVCoCVM *cvm);
} ola_emv_implem_t;

...

ola_publickey_implem_t

...

Code Block
languagec
typedef struct {
	void (*flush)(void);
	tOLAError (*add)(const tOlaPubKey *key, const uint8_t *checksum);
	tOLAError (*find)(tOlaPubKey *key, uint8_t *checksum);
	tOLAError (*get_next_id)(uint8_t *idx, uint8_t *rid, int start);
	tOLAError (*commit)(void);
} ola_publickey_implem_t;

...

ola_implem_t

...

languagec

...

Code Block
breakoutModefull-width
/*
 * main.c
 *
 *  Created on: Mar 17, 2020
 *      Author: amadis
 */

//---------------------------------------------------------
//			Includes
//---------------------------------------------------------
#include "ola.h"
#include "gpi.h" // APDU file read

#include <stdio.h>

void logOLATester(char* data)
{
	if(data)
	{
		printf("%s",data);
	}
}

static uint8_t MCW_DATA[] = // From TMS system
{
	0x9F,0x06,0x07,0xA0,0x00,0x00,0x00,0x04,0x10,0x10, // Application AID. Not used by L2 but standard EMV
	0xCE,0x01,0x00, // Not used by L2
	0xD0,0x01,0x06, // Not used by L2
	0xCB,0x01,0x03,// Not used by L2
/**/	0xDF,0x1B,0x01,0x01,
/**/	0xDF,0x4B,0x03,0x00,0x00,0x30,
	0xDF,0x1C,0x01,0x00, // Not used by L2 (TAG_MAXIMUM_TARGET_PERCENTAGE_FOR_BIASED_RANDOM_SELECTION)
/**/	0xDF,0x2D,0x06,0x00,0x99,0x99,0x99,0x99,0x99,
/**/	0xDF,0x2E,0x06,0x00,0x00,0x00,0x00,0x00,0x01,
/**/	0xDF,0x30,0x14,0x95,0x05,0xC5,0x01,0xCA,0x04,0xD0,0x01,0xD2,0x01,0xCC,0x10,0x9F,0x34,0x03,0x9F,0x41,0x04,0x8A,0x02,
/**/	0xDF,0x31,0x06,0x00,0x00,0x00,0x01,0x00,0x00,
	0xDF,0x1D,0x01,0x00, // Not used by L2 (TAG_TARGET_PERCENTAGE_FOR_RANDOM_SELECTION)
	0x9F,0x1B,0x04,0x00,0x00,0x27,0x10, // Terminal Floor Limit
	0xDF,0x21,0x04,0x00,0x00,0x00,0x00, // Not used by L2 (TAG_THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION)
	0x9F,0x53,0x01,0x01, // Transaction Category Code. Not used by L2 but standard EMV
/**/	0xDF,0x22,0x06,0x00,0x00,0x00,0x01,0x00,0x00,
/**/	0xDF,0x23,0x06,0x00,0x00,0x00,0x03,0x00,0x00,
/**/	0xDF,0x25,0x02,0x00,0x05,
	0x9F,0x4E,0x3B,	0x43,0x68,0x61,0x6D,0x70,0x20,0x64,0x65,0x20,0x4D,0x61,0x72,0x73,0x2C,0x20,0x35,0x20,0x41,0x76,0x65,0x6E,0x75,0x65,0x20,0x41,0x6E,0x61,0x74,
					0x6F,0x6C,0x65,0x20,0x46,0x72,0x61,0x6E,0x63,0x65,0x2C,0x20,0x37,0x35,0x30,0x30,0x37,0x20,0x50,0x61,0x72,0x69,0x73,0x2C,0x20,0x46,0x72,0x61,
					0x6E,0x63,0x65, // Merchant Name And Location. Not used by L2 but standard EMV
	0x9F,0x15,0x02,0x53,0x99, // Merchant Category Code. Not used by L2 but standard EMV
	0x9F,0x16,0x0F,0x52,0x43,0x54,0x53,0x54,0x30,0x30,0x30,0x30,0x30,0x34,0x36,0x31,0x33,0x37, // Merchant ID. Not used by L2 but standard EMV
	0x9F,0x01,0x06,0x01,0x00,0x09,0x28,0x73,0x51, // Acquirer ID. Not used by L2 but standard EMV
/**/	0xDF,0x41,0x0A,0x4D,0x41,0x53,0x54,0x45,0x52,0x43,0x41,0x52,0x44,
/**/	0xDF,0x27,0x05,0x8E,0xC0,0x21,0xF0,0xF2,
/**/	0xDF,0x28,0x02,0xF8,0x40,
	0xDF,0x81,0x18,0x01,0x00, // TAG_CVM_CAPABILITY_CVM_REQUIRED
	0xDF,0x81,0x19,0x01,0x08, // TAG_CVM_CAPABILITY_NO_CVM_REQUIRED
	0xDF,0x1A,0x03,0x9F,0x37,0x04, // why not DF 81 1A? Looks like default UDOL
	0xDF,0x81,0x30,0x01,0x0A, // TAG_HOLDTIME_VALUE
	0xDF,0x81,0x1B,0x01,0x20, // TAG_KERNEL_2_CONFIGURATION
	0xDF,0x81,0x1E,0x01,0xF0, // TAG_MAGSTRIPE_CVM_CAPABILITY_CVM_REQUIRED
	0xDF,0x81,0x2C,0x01,0x00, // TAG_MAGSTRIPE_CVM_CAPABILITY_NO_CVM_REQUIRED
	0xDF,0x81,0x2D,0x03,0x00,0x00,0x30, // TAG_MESSAGE_HOLD_TIME
/**/	0xDF,0x2C,0x07,0xF0,0x00,0x00,0x00,0x00,0x0F,0xC0,
	0xDF,0x81,0x31,	0x28,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x20,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x20,0x00,0x00,0x02,0x00,
					0x00,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,  // Not used by L2
	0xDF,0x81,0x24,0x06,0x00,0x00,0x00,0x00,0x30,0x00, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM
	0xDF,0x81,0x25,0x06,0x00,0x00,0x00,0x01,0x00,0x00, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_DEVICE_CVM
	0xDF,0x81,0x26,0x06,0x00,0x00,0x00,0x00,0x30,0x00, // TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT
/**/	0xDF,0x32,0x0A,0x4D,0x61,0x73,0x74,0x65,0x72,0x43,0x61,0x72,0x64,
	0xDF,0x1E,0x05,0xFC,0x50,0x80,0x88,0x00, // TAG_TAC_DEFAULT
	0xDF,0x1F,0x05,0x00,0x00,0x00,0x00,0x00, // TAG_TAC_DENIAL
	0xDF,0x20,0x05,0xFC,0x50,0x80,0x88,0x00, // TAG_TAC_ONLINE
	0x9F,0x1D,0x08,0x0C,0x3A,0x80,0x00,0x00,0x00,0x00,0x00, // Terminal Risk Management Data. Not used by L2 but standard EMV
/**/	0xDF,0x19,0x01,0x03,
/**/	0xDF,0x24,0x01,0x90,
	0x9F,0x1C,0x08,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31, // Terminal Identification. Not used by L2 but standard EMV
	0xC5,0x01,0x05 // Not used by L2
};

static uint8_t VIS_DATA[] = // From TMS system
{
	0x9F,0x06,0x07,0xA0,0x00,0x00,0x00,0x03,0x10,0x10, // Application AID. Not used by L2 but standard EMV
	0xCE,0x01,0x00, // Not used by L2
	0xD0,0x01,0x06, // Not used by L2
	0xCB,0x01,0x01, // Not used by L2
/**/	0xDF,0x1B,0x01,0x01,
/**/	0xDF,0x4B,0x03,0x00,0x00,0x30,
	0xDF,0x1C,0x01,0x00, // Not used by L2 (TAG_MAXIMUM_TARGET_PERCENTAGE_FOR_BIASED_RANDOM_SELECTION)
/**/	0xDF,0x2D,0x06,0x00,0x99,0x99,0x99,0x99,0x99,
/**/	0xDF,0x2E,0x06,0x00,0x00,0x00,0x00,0x00,0x01,
/**/	0xDF,0x30,0x14,0x95,0x05,0xC5,0x01,0xCA,0x04,0xD0,0x01,0xD2,0x01,0xCC,0x10,0x9F,0x34,0x03,0x9F,0x41,0x04,0x8A,0x02,
/**/		0xDF,0x31,0x06,0x00,0x00,0x00,0x01,0x00,0x00,
	0xDF,0x1D,0x01,0x00, // Not used by L2 (TAG_TARGET_PERCENTAGE_FOR_RANDOM_SELECTION)
	0x9F,0x1B,0x04,0x00,0x00,0x27,0x10, // Terminal Floor Limit
	0xDF,0x21,0x04,0x00,0x00,0x00,0x00, // Not used by L2 (TAG_THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION)
	0x9F,0x53,0x01,0x01, // Transaction Category Code. Not used by L2 but standard EMV
/**/	0xDF,0x22,0x06,0x00,0x00,0x00,0x01,0x00,0x00,
/**/	0xDF,0x23,0x06,0x00,0x00,0x00,0x03,0x00,0x00,
/**/	0xDF,0x25,0x02,0x00,0x05,
	0x9F,0x4E,0x3B,0x43,0x68,0x61,0x6D,0x70,0x20,0x64,0x65,0x20,0x4D,0x61,0x72,0x73,0x2C,0x20,0x35,0x20,0x41,0x76,0x65,0x6E,0x75,0x65,0x20,0x41,0x6E,0x61,0x74,
					0x6F,0x6C,0x65,0x20,0x46,0x72,0x61,0x6E,0x63,0x65,0x2C,0x20,0x37,0x35,0x30,0x30,0x37,0x20,0x50,0x61,0x72,0x69,0x73,0x2C,0x20,0x46,0x72,0x61,
					0x6E,0x63,0x65, // Merchant Name And Location. Not used by L2 but standard EMV
	0x9F,0x15,0x02,0x53,0x99, // Merchant Category Code. Not used by L2 but standard EMV
	0x9F,0x16,0x0F,0x52,0x43,0x54,0x53,0x54,0x30,0x30,0x30,0x30,0x30,0x34,0x36,0x31,0x33,0x37, // Merchant ID. Not used by L2 but standard EMV
	0x9F,0x01,0x06,0x01,0x00,0x09,0x28,0x73,0x51, // Acquirer ID. Not used by L2 but standard EMV
	0xDF,0x41,0x04,0x56,0x49,0x53,0x41,
	0xDF,0x27,0x05,0x8E,0xC0,0x21,0xF0,0xF2,
	0xDF,0x28,0x02,0xF8,0x40,
	0xDF,0x1A,0x03,0x9F,0x37,0x04,
	0xDF,0x44,0x01,0x00,
	0xDF,0x2C,0x07,0xF0,0x00,0x00,0x00,0x00,0x0F,0xC0,
	0xDF,0x32,0x04,0x56,0x49,0x53,0x41,
	0xDF,0x1E,0x05,0xD8,0x40,0x00,0xA8,0x00, // TAC not used by VISA
	0xDF,0x1F,0x05,0x00,0x10,0x00,0x00,0x00, // TAC not used by VISA
	0xDF,0x20,0x05,0xD8,0x40,0x00,0xF8,0x00, // TAC not used by VISA
	0xDF,0x19,0x01,0x01,
	0xDF,0x24,0x01,0x90,
	0x9F,0x1C,0x08,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31, // Terminal Identification. Not used by L2 but standard EMV
	0xC5,0x01,0x05, // Not used by L2
	0xDF,0x05,0x04,0x32,0x20,0x40,0x00,
	0xDF,0x08,0x06,0x00,0x00,0x010,0x03,0x00,0x01, // TAG_READER_CONTACTLESS_TRANSACTION_LIMIT_NO_DEVICE_CVM_PREPROCESSING
	0xDF,0x09,0x06,0x00,0x00,0x00,0x00,0x10,0x00, // TAG_READER_CONTACTLESS_FLOOR_LIMIT_PREPROCESSING
	0xDF,0x0B,0x06,0x00,0x00,0x00,0x00,0x20,0x01 // TAG_READER_CONTACTLESS_CVM_REQUIRED_LIMIT_PREPROCESSING
};

static uint8_t AGNOS_INI [] = // Specific to Agnos to illustrate proprietary initialization
{
		0xDF,0x01,0x08,'.','/','A','G','N','O','S','/',
		0xDF,0x02,0x0E,'.','/','A','G','N','O','S','/','C','A','K','e','y','s',
		0xDF,0x03,0x0B,'.','/','A','G','N','O','S','/','c','r','l',
		0xDF,0x04,0x0B,'.','/','A','G','N','O','S','/','e','f','l',
		0xDF,0x05,0x00, // pcsc not used
		0xDF,0x06,0x00, // lang not used
		0xDF,0x07,0x07,0x00,0x0F,0x04,0x0F,0x0A,0x00,0x01,
		0xDF,0x08,0x01,0x03
};

//---------------------------------------------------------
//			Definitions
//---------------------------------------------------------
int main(int argc, char** argv)
{
	uint8_t nb_candidates=0;
    uint8_t kernelId=0;
	int pse=0;
	tOlaPubKey 	key1={{0xA0,0x00,0x00,0x00,0x03},{0x05},0x08,{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08},0x01,{0x00,0x00,0x03},{0x00,0x00,0x00}};
	tOlaPubKey 	key2={{0xA0,0x00,0x00,0x00,0x04},{0xFE},0x08,{0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18},0x01,{0x00,0x00,0x03},{0x00,0x00,0x00}};
	uint8_t cs[20]="";
	unsigned char contact=0, contactless=1;

	ola_initialize_at_start_up(AGNOS_INI,sizeof(AGNOS_INI));

	ola_set_trace_function(&logOLATester);

	ola_pubkey_flush();
	ola_pubkey_add(&key1,cs);
	ola_pubkey_add(&key2,cs);

	if(contact)
	{
		ola_contact_flush_aid_supported();
		ola_contact_answer_to_reset(NULL);

		ola_contact_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x04\x10\x10",7,0);
		ola_contact_add_aid_supported((const uint8_t *)"\xB0\x12\x34\x56\x78\x12\x34",7,0);

		ola_contact_build_candidate_list(&nb_candidates,&pse);
		ola_contact_final_select_candidate(1);

		ola_emv_set_tag(0x9F02,(uint8_t*)"\x00\x00\x00\x00\x01\x50",6);
		ola_emv_set_tag(0x9F03,(uint8_t*)"\x00\x00\x00\x00\x00\x50",6);

		ola_emv_set_tag(0x9C,(uint8_t*)"\x00",1);
		ola_emv_set_tag(0x9F1A,(uint8_t*)"\x00\x00",2);
		ola_emv_set_tag(0x9F33,(uint8_t*)"\x00\x00\x00",3);
		ola_emv_set_tag(0x9F35,(uint8_t*)"\x00",1);
		ola_emv_set_tag(0x9F40,(uint8_t*)"\x00\x00\x00\x00\x00",5);

		ola_contact_initiate_transaction(metUndef);
		ola_contact_complete_transaction((const uint8_t*)"\x30\x30",(const uint8_t*)"\x00\x00\x00\x00\x00\x00\x00\x00",8);

		ola_contact_clean();
	}
	
	if (contactless)
	{
		ola_emv_set_tag(0xDF10,(uint8_t*)"\x04",1); // Mag + CL + CT = 0x45

		ola_contactless_flush_aid_supported();
		ola_contactless_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x04\x10\x10",7,0,
		        						2,
		        						MCW_DATA,sizeof(MCW_DATA));

		ola_contactless_add_aid_supported((const uint8_t *)"\xA0\x00\x00\x00\x03\x10\x10",7,0,
		        						3,
		        						VIS_DATA,sizeof(VIS_DATA));

		ola_emv_set_tag(0x9F02,(uint8_t*)"\x00\x00\x00\x00\x01\x50",6);
		ola_emv_set_tag(0x9F03,(uint8_t*)"\x00\x00\x00\x00\x00\x50",6);
		ola_emv_set_tag(0x9C,(uint8_t*)"\x00",1);
		ola_emv_set_tag(0x9A,(uint8_t*)"\x20\x10\x28",3);
		ola_emv_set_tag(0x9F21,(uint8_t*)"\12\x00\x00",3);

		ola_contactless_preprocess();
		ola_contactless_build_candidate_list(&nb_candidates);
		ola_contactless_final_select_candidate(1,&kernelId);
		ola_contactless_do_transaction();

		ola_contactless_clean();
	}

	return 0;
}