Switstack moka Terminal (SmT)
Switstack monitoring terminal is a tool that comes with moka to perform transactions in the scope development activities. It helps developers to realize specific tests, and debug EMV Level 2 flows using traces. Using a simple Command Line Interface (CLI), it is possible to trace moka very rapidly using either a PCSC reader (PCSC mode) or virtual cards (VEP-L mode).
Info
Running options are: ``` -h: displays help -c: specifies virtual card -f: specifies config -t: specifies trd -k: specifies cakeys -r: specifies revocations -m: specifies transaction mode (ct or cl) -s: specifies contact kernel ics -v: displays version
```
Info
Type of traces:
```
[DBG]: display miscellaneous traces
[SPC]: displays a reference to EMV Level 2 specification
[CERT]: displays information required to valide a certification test
[ERR]: displays errors
[WRN]: displays warnings
```
Switstack moka Terminal implements a basic EMV Level 3 logic required to certify EMV Level 2 kernels (contact and contactless). This example presents some API calls demonstrating the integration of moka. It is a very simple sequence in regards to acquirer host connection management but it covers key calls to perfrom card processing. Note that there is no specific API for a specific payment brand.
uint16_t
moka_perform_transaction(const char* vcard, const char* trd, const char* issuer)
{
uint16_t moka_error = MOKA_OK;
uint8_t buffer[GLASE_MAX_OUTPUT_SIZE_KERNEL_ACTIVATION] = "";
uint8_t dek[BUFFER_SIZE_512] = "", data[BUFFER_SIZE_512] = ""; // data maybe det or issuer response
uint16_t buffer_length = 0, dek_length = 0, data_length = 0;
moka_outcome_parameters_set_t ops;
moka_bool_t perform_start_d = MOKA_BOOL_TRUE;
uint32_t transaction_amount = 0;
/* 1. Pre-processing */
MOKA_ERROR_FUNC(s_moka_perform_pre_processing(trd, &transaction_amount));
/* 2. Card selection and presentment */
MOKA_ERROR_FUNC(moka_present_card(vcard));
/* 3. Polling ans application selection */
MOKA_ERROR_FUNC(s_moka_perform_selection(&ops));
/* 4. Kernel activation */
while (perform_start_d) {
emvco_signals_ops_initialize(&ops);
hal_os_memset(buffer, 0x00, sizeof(buffer));
buffer_length = sizeof(buffer);
MOKA_ERROR_FUNC(s_moka_activate_kernel(data, data_length, buffer, &buffer_length));
/* Search for DEK */
if (parser_tlv_utils_find_tag_from_tlv(
MOKA_TAG_STRUCT_DEK, &dek_length, dek, buffer, buffer_length) == MOKA_OK) {
hal_os_memset(data, 0x00, sizeof(data_length));
data_length = 0;
MOKA_ERROR_FUNC(de_ds_perform_operator_logic(
transaction_amount,
dek,
dek_length,
data,
&data_length));
hal_os_memset(dek, 0x00, sizeof(dek_length));
dek_length = 0;
// Set entry point with DET: todo -> use start D inbound
continue;
};
MOKA_ERROR_FUNC(s_moka_get_outcome_parameter_set(buffer, buffer_length ,&ops));
switch (ops.status)
{
case OPS_STATUS_APPROVED:
case OPS_STATUS_DECLINED:
perform_start_d = MOKA_BOOL_FALSE;
break;
case OPS_STATUS_ONLINE_REQUEST:
MOKA_UNUSED(issuer); // For now until scrpts required
hal_os_memset(data, 0x00, sizeof(data));
data_length = sizeof(data);
MOKA_ERROR_FUNC(s_moka_go_online(issuer, data, &data_length));
break;
default:
break;
}
switch (ops.start)
{
case START_B:
MOKA_ERROR_FUNC(s_moka_perform_selection(&ops));
break;
case START_D:
break;
default:
perform_start_d = MOKA_BOOL_FALSE;
break;
}
};
/* 5. Card removal */
MOKA_ERROR_FUNC(card.remove());
return MOKA_OK;
}