Skip to main content

Application Development Kit (Version 4.8)


ADK-TEC Programmers Guide

Last updated: 13-Jun-2025

This document is for programmers and developers who want to understand and use the ADK-TEC.

Audience

This guide provides all the information required for application developers to integrate and utilize the functionality of the ADK-TEC.

Organization

This guide is organized as follows:

Introduction: Provides a summary of ADK-TEC.

Use Cases: Presents typical flows.

Getting Started: Presents an introduction in ADK-TEC usage.

Programming: Supplies ADK-TEC programming information.

System Setup and Requirements: Supplies information about required dependencies.

PP1000: Supplies information about pairing and PIN transfer with PP1000.

Troubleshooting: Gives solutions for possible issues in ADK-TEC.

Appendix: Links to related documents.

Introduction

ADK-TEC provides technology selection functionality. Supported technologies are

  • Magstripe cards
  • EMV contact chip cards
  • EMV contactless cards and mobile phones
  • Contactless NFC cards (Mifare, Felicy, ISO, ...)
  • Contactless Value Added Service (VAS) solutions

To make use of ADK-TEC you need the following components:

Additionally you need

Flow Overview

On terminal startup the application needs to setup the components (see below picture, dashed lines):

Package name Description
tec-doc-x.x.x-xx.zip Documentation
ADK-MSR ADK-EMV Contact ADK-EMV Contactless ADK-NFC ADK-TEC (black line)
MSR_SetOptions() if desired EMV_CT_Init_Framework() EMV_CTLS_Init_Framework() NFC_Client_Init() cts_SetOptions() if desired
EMV_CT_SetTermData() EMV_CTLS_SetTermData() NFC_Terminal_Config()
EMV_CT_SetAppliData() EMV_CTLS_SetAppliDataSchemeSpecific() NFC_VAS_UpdateConfig()
EMV_CT_StoreCAPKey() EMV_CTLS_StoreCAPKey()

Transaction flow:

  • Application prepares components (dashed lines):
  • Application starts card detection
    • invoke cts_StartSelection() (black line)
    • ADK-TEC starts a thread to poll the involved components (solid blue lines)
  • User swipes, inserts, or taps a card (or mobile phone)
    • ADK-TEC gets notification about this event (solid blue lines)
  • ADK-TEC signals card detection to the application (black line)
  • Application completes the transaction (dashed lines)
    • if a magstripe card was swiped:
      • use ADK-MSR functions to fetch the read data
    • if a card was inserted:
      • use ADK-EMV Contact to make the transaction
    • if a card (or mobile phone) was tapped:
      • if CTLS EMV is signaled:
        • transaction was already done
        • use ADK-EMV Contactless to fetch the results
      • if CTLS NFC or VAS is signaled:
        • use ADK-NFC to realize the desired APDUs
        • if desired (and possible): do EMV transaction by means of ADK-EMV Contactless

Android

In Android the ADK-TEC is hidden inside SDI. So application has to use the "Card Detection (23-01)" from ADK-SDI Programmers Guide.

VOS3

In VOS3 ADK-TEC is accessible through SDI. The ADK-TEC-interface is rebuild in ADK-SDI-Client Programmers Guide.

Two-Piece Solution

Former Two-Piece Solution with Client/Server architecture for MSR, TEC, ... is not supported anymore.

SDI EPP has to be used instead (see ADK-SDI Programmers Guide).

Use Cases

Magstripe and EMV Contact, on Contactless EMV and transparent ISO APDU

Requirement:

All three technologies shall be detected: Magstripe Card Swipe, Contact Chipcard Insertion, Contactless Card (or Mobile Phone) Tap.

On Contactless interface an EMV payment shall be done.

Flow (see below diagram):

If not CTS_PURE_CARD_DETECTION: Before EVERY start the application has to set up EMV Contactless (call EMV_CTLS_SetupTransaction()).

To start technology selection the application calls cts_StartSelection() with CTS_CHIP, CTS_MSR, and CTS_CTLS.

TEC component will start a thread to poll for swipe, insert or tap.

Once a card (or mobile phone) is detected the application gets the result by means of cts_WaitSelection().

Parameter usedTechnology informs which technology is used:

  1. CTS_MSR: A magnetic card was swiped.

    Application has to read the magstripe data (with help of ADK-MSR Programmers Guide) and process transaction.
  2. CTS_CHIP: A contact chip card was inserted.

    Chip may already be activated (depending on CTS_NO_POWERON).

    Application has to execute the chip transaction by means of ADK-EMV Contact Programmers Guide.
  3. CTS_CTLS: A contactless card or mobile phone was tapped (see ADK-EMV Contactless Programmers Guide).

Magstripe and EMV Contact, on Contactless NFC

Requirement:

All three technologies shall be detected: Magstripe Card Swipe, Contact Chipcard Insertion, Contactless Card (or Mobile Phone) Tap.

On Contactless interface several card types shall be handled: MiFare, Felica, EMV, and others.

Flow (see below diagram):

To start technology selection the application calls cts_StartSelection() with CTS_CHIP, CTS_MSR, and CTS_CTLS.

Additionally CTS_NFC_ENABLE and options[12..15] (NFC technologies) have to be set.

TEC component will start a thread to poll for swipe, insert or tap.

Once a card (or mobile phone) is detected the application gets the result by means of cts_WaitSelection().

Parameter usedTechnology informs which technology is used:

Automatically perform an EMV Contacless transaction:

The application may set CTS_EMV_AFTER_NFC_ISO.

In that case it also needs to call EMV_CTLS_SetupTransaction() before cts_StartSelection().

ADK-TEC will perform an EMV contactless transaction if an ISO14443 card is tapped.

If another card is used the application will get the above mentioned NFC results.

Magstripe and EMV Contact, on Contactless EMV and VAS (Value Added Services, Wallets)

Requirement:

All three technologies shall be detected: Magstripe Card Swipe, Contact Chipcard Insertion, Contactless Card (or Mobile Phone) Tap.

On Contactless interface it's needed to handle Value Added Services (VAS) Wallets and EMV payments.

Flow (see below diagram):

Application has to prepare ADK-NFC by means of NFC_VAS_PreLoad() (see ADK-NFC Programmers Guide).

If the used VAS config includes "Pay" (= EMV) than EMV_CTLS_SetupTransaction() is needed.



To start technology selection the application calls cts_StartSelection() with CTS_CHIP, CTS_MSR, and CTS_CTLS.

Additionally CTS_VAS_ENABLE has to be set.

TEC component will start a thread to poll for swipe, insert or tap.

Once a card (or mobile phone) is detected the application gets the result by means of cts_WaitSelection().

Parameter usedTechnology informs which technology is used:

Getting Started

The following two examples show how to use technology selection (ADK-TEC):

Sample1: Application using ADK-TEC without callback

#include "tec/tec.h"#include "msr/msr.h"#include "EMV_CT_Interface.h"#include "EMV_CTLS_Interface.h".... a) MSR, CT, CTLS EMV only// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);// setup transactionEMV_CTLS_SetupTransaction(...);// start technology selection without callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, NULL, NULL, NULL, 0) == CTS_OK) b) MSR, CT, CTLS EMV + WALLET (Remark: NFC ADK supports EITHER VAS processing OR PassTrough processing, mutual exclusive)unsigned char options[2] = {0};// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);NFC_Client_Init(...);NFC_Terminal_Config(...);NFC_VAS_UpdateConfig(...);cts_SetOptions(...); // to set VAS appID// setup transaction:EMV_CTLS_SetupTransaction(...);NFC_VAS_PreLoad(...);options[1] = CTS_VAS_ENABLE;// start technology selection without callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, NULL, NULL, options, 2) == CTS_OK) c) MSR, CT, CTLS EMV + NFC Pass Through (Remark: NFC ADK supports EITHER VAS processing OR PassTrough processing, mutual exclusive)unsigned char options[16] = {0};// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);NFC_Client_Init(...);// setup transaction:EMV_CTLS_SetupTransaction(...);options[1] = CTS_NFC_ENABLE;options[1] |= CTS_EMV_AFTER_NFC_ISO; // optionaloptions[15] = 0x0F; // select card types  // start technology selection without callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, NULL, NULL, options, 16) == CTS_OK){  unsigned char technology;  unsigned char tlv_response = false;  unsigned char data[100];  unsigned short data_len = sizeof(data);  int ret;    // wait for result:  while ((ret = cts_WaitSelection(&technology, data, data_len, 100)) == CTS_IN_PROGRESS)  {    // if abort request arrived (from GUI, ECR, ...) stop technology selection:    if (aborted) cts_StopSelection();  }  switch (ret)  {    case CTS_OK: // technology detected            if(technology & CTS_DATA_TLV)      {        // clear TLV response flag        technology &= ~CTS_DATA_TLV;        tlv_response = true;      }            switch (technology)      {        case CTS_MSR:          MSR_GetData(...);          MSR_Deactivate(...);          break;        case CTS_CHIP:          EMV_CT_ContinueOffline(...);          EMV_CT_ContinueOnline(...);          // wait for removal of chip card          cts_WaitCardRemoval2(10);          break;        case CTS_CTLS:          if (tlv_response)          {            // Evaluate the response tags for NFC Pass Through, NFC VAS processing, and EMV processing if configured in b) or c) above.           }          else          {            EMV_CTLS_ContinueOffline(...);            EMV_CTLS_ContinueOnline(...);          }          break;      }      break;    case CTS_TIMEOUT: // no technology detected      break;    case CTS_STOPPED: // technology selection aborted      break;    default: // error (see cts_WaitSelection() for details about all possible return values)      break;  }}else{  EMV_CTLS_Break();}....

Sample2: Application using ADK-TEC with callback

#include <pthread.h>#include "tec/tec.h"#include "msr/msr.h"#include "EMV_CT_Interface.h"#include "EMV_CTLS_Interface.h"....static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t condition = PTHREAD_COND_INITIALIZER; static  unsigned char technology;static  unsigned char data[100];static  unsigned short data_len = sizeof(data);static  int ret; static void tecselCallback(void *data){  pthread_mutex_lock(&mutex);  ret = cts_WaitSelection(&technology, data, data_len, 0)  pthread_cond_signal(&condition);  pthread_mutex_unlock(&mutex);} .... a) MSR, CT, CTLS EMV only// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);// setup transactionEMV_CTLS_SetupTransaction(...);// start technology selection with callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, &tecselCallback, NULL, NULL, 0) == CTS_OK) b) MSR, CT, CTLS EMV + WALLET (Remark: NFC ADK supports EITHER VAS processing OR PassTrough processing, mutual exclusive)unsigned char options[2] = {0};// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);NFC_Client_Init(...);NFC_Terminal_Config(...);NFC_VAS_UpdateConfig(...);cts_SetOptions(...); // to set VAS appID// setup transaction:EMV_CTLS_SetupTransaction(...);NFC_VAS_PreLoad(...);options[1] = CTS_VAS_ENABLE;// start technology selection with callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, &tecselCallback, NULL, options, 2) == CTS_OK) c) MSR, CT, CTLS EMV + NFC Pass Through (Remark: NFC ADK supports EITHER VAS processing OR PassTrough processing, mutual exclusive)unsigned char options[16] = {0};// initialize:EMV_CT_InitFramework(...);EMV_CTLS_InitFramework(...);NFC_Client_Init(...);// setup transaction:EMV_CTLS_SetupTransaction(...);options[1] = CTS_NFC_ENABLE;options[1] |= CTS_EMV_AFTER_NFC_ISO; // optionaloptions[15] = 0x0F; // select card types   // start technology selection with callback:if (cts_StartSelection(CTS_CHIP|CTS_CTLS|CTS_MSR, 10, &tecselCallback, NULL, options, 16) == CTS_OK){  unsigned char tlv_response = false;    pthread_mutex_lock(&mutex);  // wait for callback:  pthread_cond_wait(&condition, &mutex);  pthread_mutex_unlock(&mutex);   switch (ret)  {    case CTS_OK: // technology detected            if(technology & CTS_DATA_TLV)      {        // clear TLV response flag        technology &= ~CTS_DATA_TLV;        tlv_response = true;      }            switch (technology)      {        case CTS_MSR:          MSR_GetData(...);          MSR_Deactivate(...);          break;        case CTS_CHIP:          EMV_CT_ContinueOffline(...);          EMV_CT_ContinueOnline(...);          // wait for removal of chip card          cts_WaitCardRemoval2(10);          break;        case CTS_CTLS:          if (tlv_response)          {            // Evaluate the response tags for NFC Pass Through, NFC VAS processing, and EMV processing if configured in b) or c) above.           }          else          {            EMV_CTLS_ContinueOffline(...);            EMV_CTLS_ContinueOnline(...);          }          break;      }      break;    case CTS_TIMEOUT: // no technology detected      break;    case CTS_STOPPED: // technology selection aborted      break;    default: // error (see cts_WaitSelection() for details about all possible return values)      break;  }}else{  EMV_CTLS_Break();}....

Link your application with libtec.so and load the shared library libtec.so on your device. If you don't want to periodically call cts_WaitSelection() you can supply a callback function to cts_StartSelection(). This callback function is called exactly once after the technology selection has finished (due to detected technology, timeout, or error). After this callback function has been called (or even withing the callback function) you can obtain the result by cts_WaitSelection() setting its timeout to 0. A callback function is supported for card removal detection as well (see cts_WaitCardRemoval()).

Programming

Programming and API Principles

The API consists of the following functions:

tec.h
cts_Version()
cts_SetTraceCallback()
cts_SetOptions()
cts_StartSelection()
cts_StopSelection()
cts_WaitSelection()
cts_RemoveTechnologies()
cts_AddTechnologies()
cts_WaitCardRemoval()
cts_WaitCardRemoval2()
ped_SetSendRcvCb()
ped_Pairing()
ped_MovePin()
cts_SetNotificationCallback()

Some notes regarding the different technologies

In general only one of CTS_MSR, CTS_CHIP, CTS_CTLS is detected but in special cases (see Detecting MSR and CTLS simultaneously and Special behavior on hybrid readers (UX30x)) two technologies can be detected at once.

Processing NFC with ADK-TEC

This is the general routine used in ADK-TEC for detecting and processing CTLS cards (pseudocode), it should help you to understand how ADK-TEC behaves depending on the various CTLS options.

[0] if both CTS_NFC_ENABLE and CTS_VAS_ENABLE are set:        exit    end[1] if CTS_NFC_ENABLE is set:        call NFC_PT_Polling()        if ISO A/B card found and CTS_EMV_AFTER_NFC_ISO is set:            goto [3]        end        exit    end[2] if CTS_VAS_ENABLE is set:        call NFC_VAS_Activate()        if VAS_DO_PAY is returned:            goto [3]        end        exit    end[3] if CTS_PURE_CARD_DETECTION is set:        call EMV_CTLS_SmartReset()    else        call EMV_CTLS_ContinueOffline()    end

If it is possible that EMV_CTLS_ContinueOffline() is called by ADK-TEC, application has to call EMV_CTLS_SetupTransaction() before starting technology selection. If ADK-TEC detects a card with NFC_PT_Polling() and no subsequent EMV transaction is started, ADK-TEC keeps the RF field on to allow the application to communicate with this card. In this case the application has to call NFC_PT_FieldOff() and NFC_PT_Close() afterwards. Furthermore the first CTLS LED is left on by ADK-TEC in this case. The application generally wants it to shine while communicating with the card or even wants to switch on further LEDs. So as soon as the application has finished the transaction, it needs to switch off the LEDs or restart idle blinking.

Detecting MSR and CTLS simultaneously

After CTS_CTLS has been detected technology selection can wait a certain amount of time for CTS_MSR before returning the result to the application. If a magnetic card is swiped within this period of time technology selection will return CTS_CTLS|CTS_MSR as technology. The timeout can be configured by the options parameter of cts_StartSelection().

Special behavior on hybrid readers (UX30x)

Hybrid readers have a single slot for handling magstripe and contact chip.

ADK-TEC provides special functionality to help the application in making the decision which technology to choose.

ADK-MSR Configuration

When using an UX30x device it is strongly recommended to activate the MSR UX enhancements (see ADK-MSR Programmers Guide):

unsigned char options[] = { MSR_UX_ENHANCEMENTS };MSR_SetOptions(options, sizeof(options));

This has to be done only once, before the first call of cts_StartSelection(). These enhancements will prevent MSR from reading the magnetic card on insertion.

If the MSR UX enhancements are not activated, the following remarks are valid as well. Additionally it is possible that technology selection detects both CTS_MSR and CTS_CHIP in parallel.

Use Case: Technologies Contact Chip and Magstripe are supported

cts_StartSelection() is called with requesting technology CTS_CHIP (and CTS_MSR).

CTS_CTLS may or may not be activated.

Use Case: Technology Magstripe supported but Contact Chip NOT

cts_StartSelection() is called with requesting technology CTS_CHIP (and CTS_MSR).

CTS_CHIP is necessary to be able to detect the card insertion.

CTS_NO_POWERON shall be set to avoid activation of chip card.

CTS_CTLS may or may not be activated.

ADK-TEC legacy timeout handling

Above shown diagrams are recommended handling.

For downward compatibility the following functionality is still supported.

System Setup and Requirements

Compiler and Linker Settings

include tec.h and link libtec.so

libtec defines it's dependencies to other libs in needed section (you can show that by "objdump -p libtec | grep NEEDED")

Hardware

ADK-TEC is hardware platform agnostic and supports installation on V/OS and VOS2 terminals.

Software

ADK-TEC is designed to be platform agnostic and will be supported on V/OS and VOS2 terminal operating systems.

Deliverables and Deployment

Packages delivered (x - version number digit):

Package name Description
tec-doc-x.x.x-xx.zip Documentation
tec-vos-dev-x.x.x-xx.zip VOS development package, to be installed in PC build environment
tec-vos2-dev-x.x.x-xx.zip VOS2 development package, to be installed in PC build environment

PP1000

Pairing and PIN transfer with PP1000

ADK-TEC is capable of performing pairing a countertop device (CTP) with a PP1000 device and transferring the PIN entered at the PP1000 into the vault of the countertop device. On the PP1000 you only need to install the current AQUILA version, no ADK-TEC component is running on the PP1000. The application running on the CTP needs to include the header file ped.h which is provided by ADK-TEC. Within this file the three functions ped_SetSendRcvCb(), ped_Pairing(), and ped_MovePin() are declared. If you call one of these functions you have to additionally install the library libPP1000.so on the CTP. This library is shipped together with ADK-TEC. ped_Pairing() pairs the two devices. The actual pairing is only to be done once. However, if one of the devices is paired with a third device in between, the devices must be repaired. ped_Pairing() first checks if the two devices are successfully paired and performs the pairing only if this is necessary.

If the pairing is successful, a PIN can be transferred from PP1000 to CTP. The function ped_MovePin() does not collect the PIN on the PP1000, so the PIN entry must be triggered by the application. It can directly send the commands to the PP1000 or use the function pp1000_acceptPin() which is provided by libPP1000. After the PIN has been entered, the PIN can be transferred into the vault of the CTP by calling ped_MovePin(). If this is successfully done, the application can proceed as usual, e.g. call EMV_CT_Send_PIN_Offline() if this is an offline PIN.

The communication between PP1000 and CTP has to be handled on application level. Both ADK-TEC and PP1000 lib are platform independent and do not have communication built in. The application has to call either ped_SetSendRcvCb() (provided by ADK-TEC) or pp1000_registerComs() (provided by PP1000 lib) to set functions that send and receive data to/from the PP1000. So the application can freely decide which communication method it wants to use, e.g. you may use ADK-COM or directly call OS functions.

Troubleshooting

Frequently Asked Questions

Q: cts_WaitSelection->timeout_msec: What is the purpose of this timeout if compare with cts_StartSelection->timeout_sec? Provide use cases.

A: cts_StartSelection->timeout_sec is the timeout for the whole technology selection process, e.g. 30 seconds might be reasonable value. cts_WaitSelection->timeout_msec is the timeout for the cts_WaitSelection() function. It blocks and returns only if the timeout expires (in this case CTS_IN_PROGRESS is returned) or a result is available (something != CTS_IN_PROGRESS is returned). The timeout value to use here depends on your application design. If you have set a callback function to cts_StartSelection(), this callback is invoked as soon as a result is available. So you have to call cts_WaitSelection() exactly once after the callback is invoked, set timeout=0 (waiting makes no sense because you know that a result is available) If you do not want to use callback function you can call cts_WaitSelection() with different timeout values. If you have set timeout in cts_StartSelection() to 30 seconds, the easiest thing to do is set cts_WaitSelection->timeout_msec to 35000 ms (maybe even longer if you set options[8..9] because this may prolongate the technology selection). Then you have to call cts_WaitSelection() only once, it blocks and returns as soon as a result is available. This works of course only if cts_StartSelection->timeout_sec does not exceed ~60 seconds. If you set cts_WaitSelection->timeout_msec to smaller values you have to call the function in a loop until a result (something != CTS_IN_PROGRESS) is returned. This makes sense if you want to do other things in the same thread while waiting for result of technology selection, e.g. you may want to call cts_StopSelection() if abort request arrived from GUI or ECR. So in this case the timeout depends on the frequency with that you want to do the other things, e.g. a timeout of 0 is possible but will lead to high system load wheras a timeout of 100ms seems reasonable.

Q: Some time ago, upon reviewing our test logs, you pointed out that we should not call the API MSR_Activate() if next we start the selection with the API cts_StartSelection() because the latter activates the reader by itself. And what about the scenario when we want to establish the MSR callback and then use the selection? Here, MSR_Activate() is the only way to establish such a callback. Is this a legal use case to use simultaneously the MSR callback and the selection which, in turn, may have its own callback?

A: No, this is not a legal use case. You should not establish the MSR callback if you use technology selection. This is confusing and not necessary anyway. If MSR data is available, technology selection will finish, so you get the information from TEC, no need to set MSR callback. If you even call MSR_GetData() upon receiving MSR callback, TEC would most likely not be able to detect that MSR data is available and continue waiting for technology (TEC calls MSR_DataAvailable() and as soon as MSR_GetData() is called, the former will return 'no data available'). So please do not do anything like this.

Logging

You have two options to enable logging, choose one of them (if you think this is helpful, you could actually use both at once):

  • Register a trace callback function with cts_SetTraceCallback().
  • Use ADK-LOG: Configure logging channel "TEC" by means of log control panel.


Appendix

Appendix is empty.

Need help?

Do you have a question? If you didn’t find the answer you are looking for in our documentation, you can contact our Support teams for more information. If you have a technical issue or question, please contact us. We are happy to help.

Not yet a Verifone customer?

We’ll help you choose the right payment solution for your business, wherever you want to sell, in-person or online. Our team of experts will happily discuss your needs.

Verifone logo