Skip to content

Sample Code

Setup

The setup consists in initializing the structure of the system, i.e. the message broker and all the services to be used. To do so, you shall use switstack moka's manager that exposes an API to allocate memory space and register the functional components.

Service Description Release Status
SERVICE_TYPE_CPA_1 Deprecated. N/A.
SERVICE_TYPE_CPA_MASTERCARD EMVCo Book C-2 implementation. Qualification in progress.
SERVICE_TYPE_CPA_VISA Visa specifications implementation. Qualification in progress.
SERVICE_TYPE_CPA_AMEX American Express specifications implementations. Qualification in progress.
SERVICE_TYPE_CPA_5 JCB specifications implementations. To be planned.
SERVICE_TYPE_CPA_6 Discover specifications implementations. Development in progress.
SERVICE_TYPE_CPA_7 CUP-QuickPass Overseas specifications implementations. To be planned.
SERVICE_TYPE_CPA_8 EMVCo Book C-8 implementation. To be planned.
SERVICE_TYPE_CPA_9 RFU. N/A.
SERVICE_TYPE_CPA_10 RFU. N/A.
SERVICE_TYPE_CPA_11 RFU. N/A.
SERVICE_TYPE_CPA_12 RFU. N/A.
SERVICE_TYPE_CPA_13 RFU. N/A.
SERVICE_TYPE_CPA_14 RFU. N/A.
SERVICE_TYPE_CPA_15 RFU. N/A.
SERVICE_TYPE_ENTRY_POINT EMVCo Books A/B implementation. Available.
SERVICE_TYPE_READER Card coupling, and SRED module. Available.
SERVICE_TYPE_PINPAD PIN capture and PIN block encipherment. Roadmaped.
SERVICE_TYPE_HSM CAPK storage. Available.
SERVICE_TYPE_DISPLAY Output. Available.
SERVICE_TYPE_CARD Card simulation. Available.
SERVICE_TYPE_LOGGER Machine readable log generator. Available.
SERVICE_TYPE_GLASE Generic EMV Level 2 encapsulation. Available.
SERVICE_TYPE_APPLICATION Any application used to inteface switstack moka to external an software system. To be planned.

Info

All kernels are qualified against payment networks test plans and automated test plans are made available for faster qualification. EMVCo certifications are not targeted, excepted for EMVCo Book C-8.

So, the programmatic sequence should be as followed:

Store a list of services

Each entry of this table corresponds to the service's entry point address, i.e. the proxy.

    static moka_service_proxy_t my_routing_table[NUMBER_OF_SERVICES];

Instantiate message broker

    static moka_message_broker_t g_my_message_broker;

Allocate memory to store EMV tags

    static uint8_t g_entry_point_storage[2500] = ""; // Contactless comnbinations.
    static uint8_t g_tags_storage[5000] = ""; //  EMV transactions.

Set up services

    uint16_t
    moka_setup(void)
    {
        srv_mng_reset();

        /* Setup services manager */
        srv_mng_initialize_services_manager(&g_my_message_broker, my_routing_table, NUMBER_OF_SERVICES);

        srv_mng_set_services_data_storage(
            g_tags_storage,
            sizeof(g_tags_storage),
            g_entry_point_storage,
            sizeof(g_entry_point_storage));

        /* Add services */
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_CARD);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_READER);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_ENTRY_POINT);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_CPA_MASTERCARD);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_GLASE);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_LOGGER);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_HSM);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_DISPLAY);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_CPA_VISA);
        srv_mng_add_service(&g_my_message_broker, SERVICE_TYPE_CPA_AMEX);

        /* Start message broker */
        srv_mng_setup_services();

        return MOKA_OK;
    }

Note

SERVICE_TYPE_CARD is used to simualte cards and enable EMV software-defined testing.

Configuration`

The configuration consists in completing the setup for specific services that require internal parameters to work properly. Like the setup, the configuration is performed only once ahead of the cycle of transactions. There are two ways to configure a service:

  1. Either use GENERIC_SERVICE_SET_PARAMETERS and send a TLV including a set of parameters;
  2. Either use a functional service that depends on the service;

Info

Use service's data models to know what parameters are available for configurations (sse Appendix).

    uint8_t key_data[BUFFER_SIZE_512] = "";
    uint16_t key_data_length = 0;
    uint8_t revocation_data[BUFFER_SIZE_64] = "";
    uint16_t revocation_data_length = 0;
    uint8_t config_data[BUFFER_SIZE_512] = "";
    uint16_t config_data_length = 0;

    // All data buffer shall be initialized with a TLV structure corresponding to moka's data model
    glase.flush_ca_keys();
    glase.add_ca_key(key_data, key_data_length);
    glase.add_revocated_certificate(revocation_data, revocation_data_length);

    // Important: the reference transaction type shall be set ahead of this call as soon as it is known
    glase.add_combination(config_data, config_data_length);

Pre-conditions

This step consists in cleaning-up the kernels, and other services. This shall be performed before aech new transaction.

    /* Prepare sred reader */
    srv_mng_initialize_service(SERVICE_TYPE_READER);
    /* Prepare mastercard kernel */
    srv_mng_initialize_service(SERVICE_TYPE_CPA_MASTERCARD);
    /* Prepare visa kernel */
    srv_mng_initialize_service(SERVICE_TYPE_CPA_VISA);
    /* Prepare amex kernel */
    srv_mng_initialize_service(SERVICE_TYPE_CPA_AMEX);

Info

Additional calls to GENERIC_SERVICE_SET_PARAMETERS may be peformed depending on the service to use. But concerning the kernels, they are mainly set from the combinations that are selected by the entry point.

Initiate Card Processing

Pre-processing

This step consists in pre-processing contactless combinations, i.e. performing a start A.

    uint8_t buffer[BUFFER_SIZE_256] = "";
    uint16_t buffer_length = sizeof(buffer);

    // trd is a TLV containing amount, other amount, currency code, etc...
    // buffer indicates number of allowed combinations
    glase.pre_processing(trd, trd, buffer, &buffer_length);

Card polling

This step consists in detecting a card, i.e. performing a start B.

    uint16_t moka_error = MOKA_OK;
    uint8_t detected_interface = HAL_NO_CARD_INTERFACE;

    glase.protocol_activation(&detected_interfaces);

Application selection

This step consists in selecting an EMV application, i.e. performing a start C.

    uint8_t buffer[BUFFER_SIZE_256] = "";
    uint16_t buffer_length;

    hal_os_memset(buffer, 0x00, sizeof(buffer));
    buffer_length = sizeof(buffer);
    glase.combination_selection(buffer, &buffer_length);

    // Fetch some tags corresponding to the selected candidate
    hal_os_memset(buffer, 0x00, sizeof(buffer));
    buffer_length = sizeof(buffer);
    glase.get_tag_from_candidate((const uint8_t*)"\x9F\x06", 2, buffer, &buffer_length);
    hal_os_memset(buffer, 0x00, sizeof(buffer));
    buffer_length = sizeof(buffer);
    glase.get_tag_from_candidate((const uint8_t*)"\x87", 1, buffer, &buffer_length);

Warning

Current version doesn't allow to get tags from a specific candidate within the entry point's candidate list. Here, the APi simply fetches 0x9F06 and 0x87 tags from the candidate implicity selected during start C prcoess (having the highest priority). This feature is not required by EMVCo and payment networks but it provides a certain level of flexibility for particualr regional markets. This feature will be included in the next version.

Kernel activation

This step consists in activating the kernel that corresponds to the EMV application selected during start C process, i.e. performing a start D.

    uint8_t buffer[BUFFER_SIZE_256] = "";
    uint16_t buffer_length;

    hal_os_memset(buffer, 0x00, sizeof(buffer));
    buffer_length = sizeof(buffer);
    glase.kernel_activation(buffer, buffer_length);

Complete Card Processing

This step is optional and corresponds to a second presentment or long tap. Once the system goes lines, the issuer responses may require to communicate again with the card. For example, issuer script management is a typical use case. This option is not supported by all kernels.

Post-conditions

This step consists in analysing the outcome of a transaction. It is required:

  • After kernel activation, and
  • After completion;

In both situations, the application level need to get some tags to take decisions, and prepare online messahe or even capture information for batches. All tags can read fron a single call using the following API:

    uint8_t buffer[BUFFER_SIZE_256] = "";
    uint16_t buffer_length;

    glase.get_tag((const uint8_t*)"\x9F\x33\x5A", 3, buffer, buffer_length);

Info

With switstack moka, all EMV data objects are managed as tags including the signals. Use outcome parameter set signal to get the final outcome, for example.