Amadis

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

Online documentation (Javadoc)

The online API documentation can be found at the following address: https://fbe-host.ca/agnos/agnos-2.0.0-javadoc/index.html .

Basic transaction

A basic OLA transaction includes the following steps:

OLA classes instantiation (once at startup)

private final Ola ola;                                                                                                  
private final OlaEmv emv;                                                                                               
private final OlaContactless contactless;

this.ola = Ola.getInstance();
this.contactless = OlaContactless.getInstance();
this.emv = OlaEmv.getInstance();

OLA component initialisation (once at startup)

/**
 * Configures OLA layer (key files paths, trace, etc...)
 */
private void olaConfig() {

    final byte[] path = {(byte)0xdf, 0x01, 28};
    final String pathValue = "/data/data/ca.amadis.tester/";
    final byte[] cakeys = {(byte)0xdf, 0x02, 34};
    final String cakeysValue = "/data/data/ca.amadis.tester/CAKeys";
    final byte[] crl = {(byte)0xdf, 0x03, 31};
    final String crlValue = "/data/data/ca.amadis.tester/CRL";
    final byte[] efl = {(byte)0xdf, 0x04, 31};
    final String eflValue = "/data/data/ca.amadis.tester/EFL";
    final byte[] pcsc = {(byte)0xdf, 0x05, 0x00}; // pcsc not used
    final byte[] lang = {(byte)0xdf, 0x06, 0x00}; // lang not used
    final byte[] runtimeParams = {(byte)0xdf, 0x07, 0x07, 0x00, 0x0F, 0x04, 0x0F, 0x0A, 0x00, 0x01};
    final byte[] traceLevel = {(byte)0xdf, 0x08, 0x01, 0x05};
    final byte[] pollingTechno = {(byte)0xdf, 0x10, 0x01, 0x04}; // Contactless only
    final byte[] sredMode = {(byte)0xdf, 0x17, 0x01, 0x01}; // SRED mode active

    try 
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        out.write(path);
        out.write(pathValue.getBytes());
        out.write(cakeys);
        out.write(cakeysValue.getBytes());
        out.write(crl);
        out.write(crlValue.getBytes());
        out.write(efl);
        out.write(eflValue.getBytes());
        out.write(pcsc);
        out.write(lang);
        out.write(runtimeParams);
        out.write(traceLevel);
        out.write(pollingTechno);
        out.write(sredMode);

        byte[] tlv = out.toByteArray();

        ola.initializeAtStartUp(tlv);
    } 
    catch (IOException e)
    {

    }
}

AID configuration (once at startup)

private void terminalContactlessConfig() {

    contactless.flushAIDSupported();

    for (OLAConfig.ContactlessCfg config : OLAConfig.contactlessCfg) 
    {
        contactless.addAIDSupported(
            config.aid,
            config.partial,
            (byte)config.kernelId,
            config.additionalData
        );
    }

    contactless.commitSupportedAIDs();
}

Keys configuration (once at startup)

private void terminalPublicKeyConfig() {

    publicKey.flush();

    byte rid[] = {(byte)0xA0, 0x00, 0x00, 0x00, 0x03};
    byte idx = (byte)0x92;
    byte modulus[] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
    byte exponentValue[] = {0x03};
    byte expirDate[] = {0x22, 0x12, 0x31};
    Holders.SingleObjectHolder<Boolean> wasMaxReached_holder = new Holders.SingleObjectHolder<Boolean>(false);
    OlaPublicKey.PublicKeyData key = publicKey.new PublicKeyData(rid, idx, modulus, exponentValue, expirDate);
    publicKey.add(key, null, wasMaxReached_holder);

    publicKey.commit();
}

Transaction related data (before each transaction)

private void txnSetTransactionRelatedData() {

    emv.setTag(OlaTag.TRANSACTION_DATE,              new byte[]{0x20, 0x10, 0x28});                     // 9A
    emv.setTag(OlaTag.TRANSACTION_TIME,              new byte[]{0x12, 0x00, 0x00});                     // 9F21
    emv.setTag(OlaTag.AMOUNT_AUTHORISED,             new byte[]{0x00, 0x00, 0x00, 0x00, 0x01, 0x50});   // 9F02
    emv.setTag(OlaTag.AMOUNT_OTHER_NUM,              new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x50});   // 9F03
    emv.setTag(OlaTag.TRANSACTION_CURRENCY_CODE,     new byte[]{0x08, 0x40});                           // 5F2A
    emv.setTag(OlaTag.TRANSACTION_CURRENCY_EXPONENT, new byte[]{0x02});                                 // 5F36
    emv.setTag(OlaTag.TRANSACTION_TYPE,              new byte[]{0x00});                                 // 9C

    /*
     * Other possible tags to set here:
     * Account Type (5F57)
     * Transaction Category Code (9F53)
     *
     * All other tags must be set through the combinations!
     */
}

Preprocessing

private OlaError txnPreProcess() {

    OlaError ret = contactless.preprocess();
    if (ret != OlaError.OLA_OK)
    {
        Log.e("OLA-TESTER", "contactless pre-process failed");
    }

    return ret;
}

Card detection

private short txnGetCard() {

    Log.d("OLA-TESTER", "PRESENT CARD");

    int foundTechnos = dev.technoPolling(60000);
    l("Result of foundTechnos: "+ foundTechnos);

    if (foundTechnos==4)
    {
        return clcEMV_CARD; //TODO remove hard-coding
    }
    else
    {
        return 0;
    }
}

Do transaction

private OlaError doTransaction() {

    SingleObjectHolder<Integer> nbCandidatesHolder = new SingleObjectHolder<Integer>();
    OlaError ret = contactless.buildCandidateList(nbCandidatesHolder);

    if (ret != OlaError.OLA_OK)
    {
        showOutcome(ret);
    }

    /*
     * For now, finalSelectCandidate is useless. Everything from preprocessing to card
     * processing is done in "buildCandidateList". This will change as soon as exit conditions
     * are availble in OLA 2.x, hence we keep all the function calls here
     */
    SingleObjectHolder<Byte> kernel_id_holder = new SingleObjectHolder<Byte>();
    ret = contactless.finalSelectCandidate(1, kernel_id_holder);
    if (ret != OlaError.OLA_OK)
    {
        showOutcome(ret);
    }

    ret = contactless.doTransaction();
    showOutcome(ret);

    if (ret == OlaError.OLA_OK)
    {
        SingleObjectHolder<byte[]> bytesHolder = new SingleObjectHolder<byte[]>();
        for (int olaTag : batch)
        {
            OlaError result = emv.getTag(olaTag, bytesHolder);
            if (result == OlaError.OLA_OK)
                l("Result for ola_contactless_get_tag(): "+result+" => "+ Arrays.toString(bytesHolder.get()));
            else
                l("Result for ola_contactless_get_tag(): "+result+" => tag missing");
        }
    }

    Log.d("OLA-TESTER", "**** REMOVE CARD **** ");

    return ret;
}
  • No labels