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 interface is an abstraction of the card processing (alias L2), for EMV contact and EMV contactless system. It is based on a simple set of primitives to ease L2 integration onto a payment application (alias L3).

That set of primitives supports Nexo Fast’s structures and dynamics.

What is not covered by OLA interface is:

  • Pin pad management: refer to manufacturer’s SDK to integrated use cases related to pin entry. Most of the time, proprietary callbacks must be defined using specific software signatures

  • Transit features: use manufacturer’s SDK to realize transit use cases. For example, if using Agnos Framework, refer to Callbacks 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"

...

Current OLA version.

...

logf_function

...

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

...

Callback definition used by L2 stack to trace its execution. That logging function is defined above OLA API (for example, by the L3) and called from OLA implementation or below.

...

ola_get_api_version

...

Code Block
languagec
const char *ola_get_api_version(void);

...

Gets OLA Interface version.

...

ola_get_implementation_version

...

Code Block
languagec
const char *ola_get_implementation_version(void);

...

Get OLA Implementation version. Whereas OLA Interface is independant for any L2, its implementation depends on underlying SDK. For example, if using Agnos Framework, possible implementations could be AGF 3.5.x, or AGF 3.3.x. Today, other available implementations are on AMP, Castles, and PAX terminals.

...

ola_initialize_at_start_up

...

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

...

Set specific internal states related to a given OLA implementation. For example, if using Agnos Framework, the TLV is a serialization of the following structure:

Code Block
languagec
typedef struct {
    /** Path to all configuration files (must end with '/') */
	uint8_t path[MAX_PATH_LENGTH]; // DF01
    /** CAKeys full path file name -  */
	uint8_t cakeys[MAX_PATH_LENGTH]; // DF02
    /** CRL full path file name */
	uint8_t crl[MAX_PATH_LENGTH]; // DF03
    /** EFL full path file name */
	uint8_t efl[MAX_PATH_LENGTH]; // DF04
    /** PCSC readers full path file name (.ini) */
	uint8_t pcsc[MAX_PATH_LENGTH]; // DF05
    /** Languages full path file name (.ini) */
	uint8_t lang[MAX_PATH_LENGTH]; // DF06
    /**
     * Runtime parameters
     *
     * Byte 1 - DEFAULT TXN TYPE (tag 9C)
     * Byte 2 - LEGACY SELECTION BITMAP
     * |  bit 8  7  6  5  4  3  2  1
     * |      x                       Legacy ZIP
     * |         x                    Legacy PayPass
     * |            x                 Legacy Amex
     * |               x              Legacy JCB
     * |                  x           Legacy CUP
     * |                     x        Legacy DPAS
     * |                        x     Legacy Visa
     * |                           -  RFU
     * Byte 3 - STACK PARAMETER BITMAP 1/2
     * |  bit 8  7  6  5  4  3  2  1
     * | x                       Contactless - AlwaysReceipt
     * |    x                    Agnos - CL
     * |       x                 Contactless - TransactionLooping
     * |          x              Contactless - KeyIn
     * |             x           Contactless - Signal
     * |                x        Callback - DE
     * |                   x     Agnos - APDULog
     * |                      x  Agnos - UIDisplay
     * Byte 4 - STACK PARAMETER BITMAP 2/2
     * |  bit 8  7  6  5  4  3  2  1
     * | x                       Agnos - Replay
     * |    x                    Agnos - IDMessageDisplay
     * |       x                 Agnos - TagDump
     * |          x              Contactless - DigitalSignal
     * |             -           RFU
     * |                -        RFU
     * |                   -     RFU
     * |                      -  RFU
     * Byte 5 - POLLING TIMEOUT (s)
     * Byte 6 - TRACE DEPTH (0 to 6)
     * Byte 7 - DEFAULT LANGUAGE
     */
    uint8_t params[RUNTIME_PARAM_LENGTH]; // DF07
    /** Trace level */
    uint8_t trace_level; // DF08

} tAgnosIni;

...

ola_set_trace_function

...

Code Block
languagec
void ola_set_trace_function(logf_function fct);

...

Set logging callback.

...

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

This module provides a set of primitives to manage public key certifcates (CAPK) used in EMV to support the Offline Data Authentication (ODA) process.

...

#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’s CAPK definition.

...

ola_pubkey_flush

...

Code Block
void ola_pubkey_flush(void);

...

Reset L2 stack’s CAPK. Depending on OLA implementation, it corresponds to emptying CAPK files in flash or zeroing a specific structure in RAM. After that call, no CAPK are store by L2 stack.

...

ola_pubkey_add

...

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

...

Add a CAPK into L2 stack’s. OLA Implementation creates a copy of key for further use. The checksum is optional (may be NULL) and corresponds to a SHA-1 of the tOlaPubKey instance refered by key.

...

ola_pubkey_find

...

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

...

Look up for a specific CAPK. The checksum is optional (may be NULL) and corresponds to a SHA-1 of the tOlaPubKey instance refered by key.

...

ola_pubkey_get_next_id

...

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

...

CAPK iterator. Use start = 1 to iterate from the beginning.

...

ola_pubkey_commit

...

Code Block
tOLAError ola_pubkey_commit(void);

...

Persist all previously added CAPK. Depending on OLA Implementation, it might be required to add all CAPK in a first step, then commit them in a second step for further use. This is typically dependent on L2 stack design.

...

ola_terminal

...

See ola_terminal.h

This module is not available from OLA 2.x version.

...

// Deprecated

...

N/A

...

N/A

...

ola_tags_dictionary

...

See ola_tags_dictionary.h

This module defines a series of tags defined by Nexo, and processed as being standard. Other tags part of the card processing will considered either standard by definition or proprietary, and processed accordingly by the API implementation:

  • Standard tags are processed using ola_set_emv_tag / ola_get_emv_tag

  • Proprietary tags are processed using ola_initialize_at_start_up

...

#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

This module provides a set of structures to centralize OLA services in a single C structure that can be used by the L3. It doesn’t provide specific functional services but a simple architecture mechanism to abstract OLA Interface.

...

#include

...

Code Block
languagec
#include "ola.h"

...

--

...

ola_contact_implem_t

...

Code Block
languagec
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
languagec
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

...

Code Block
languagec
typedef struct {
	ola_contact_implem_t contact;
	ola_contactless_implem_t contactless;
	ola_emv_implem_t emv;
	ola_publickey_implem_t publickey;
} ola_implem_t;

...

--

...

Code Example

...

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;
}