Namespaces | |
dpySCM | |
Deepsy SCM namespace that includes the different enums, structs or method signatures that should be used. | |
Classes | |
class | SCM |
Allows to interact with a platform manager. More... | |
Detailed Description
Smart Card Manager API related documentation
A quick overview of basic Smart Card Manager API capabilities and examples is given.
If you find Smart Card Manager API useful and would like to know more details, please check out further sections. of the Smart Card Manager API documentation or contact the Deepsy platform team.
Functionalities
- Get devices: Asynchronous operation for getting connected devices.
- Get readers: Asynchronous operation for getting readers connected to a device.
- Add keys: Asynchronous operation for adding keys to a specific device.These keys can be loaded from json file or C++ structure.
- Get keys: Asynchronous operation for getting keys from specific device.
- Remove keys: Asynchronous operation for removing keys from specific device.
- Card operation: Asynchronous operation for any operation to any smart card type.
- New card events: Subscribe to new card events, available or removed smart cards.
- Read: Synchronous operation for reading blocks or pages of Mifare Classic or Ultralight smart cards.
- Write: Synchronous operation for writing blocks or pages of Mifare Classic or Ultralight smart cards.
- APDU Exchange: Synchronous operation for exchanging APDUs to smart cards.
- Get media profiles: Asynchronous operation used to retrieve the available media profiles for a specific device.
- Add media profiles: Asynchronous operation used to add a media profile for a specific device.These media profiles can be loaded from json file or C++ structure.
- Play media profiles: Asynchronous operation playing media profiles in device.
- Get/Set PCI Data Security Standard reboot time
- PCI reboot events: Subscribe to PCI reboot events.
- Get Ultralight counter: Asynchronous and synchronous operation for getting the ultralight counter.
- Increment Ultralight counter: Asynchronous and synchronous operation for incrementing the ultralight counter.
- Pass through operation: Asynchronous/Synchronous operation used to send commands directly to the device via pass-through .
- Upgrade status: Every upgrade status change.
- Request charge for EMV: Request a EMV transaction.
- Confirm a EMV transaction: Confirm the last EMV transaction.
- Set payment application status: Set payment app status.
- Get payment application information: Get the current payment application information.
- Get payment application configuration: Get the current payment application configuration.
- Get every transaction EMV result: Get every EMV transaction result.
- Reboot a device, The reboot can be SOFT (only application) or HARD (complete device).
- Force connection: when device has lost internet connection, payment gateway connection can be force.
Examples
-
Getting available devices
#include <dpy/scmApi.h>#include <iostream>{if (ec.value() == 0) {std::cout << "\rSmart Card Manager device list: " << std::endl;for (std::vector<std::string>::size_type i = 0; i != rDevice.device.size(); i++) {std::cout << "\r- " << rDevice.device[i] << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}}int main(int argc, char *argv[]){SCM scm;scm.asyncGetDevices(print_device_list);} -
Obtaining readers from device
#include <dpy/scmApi.h>#include <iostream>#include <boost/thread.hpp>static bool get_readers = false;static bool reset_sam = false;void print_readers_list(boost::system::error_code& ec, const dpySCM::DeviceReaderList& deviceReaderList){if (ec.value() == 0) {std::cout << "\rSmart Card Manager '" << deviceReaderList.deviceId << "' reader list:" << std::endl;for (std::vector<std::string>::size_type i = 0; i != deviceReaderList.readers.size(); i++) {std::cout << deviceReaderList.readers[i].socket << ", ";std::cout << deviceReaderList.readers[i].samuid << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}get_readers = true;}void result_sync_handler(boost::system::error_code ec){if (ec) {std::cout << "\rError : " << ec.message() << std::endl;} else {std::cout << "\rSynchronous operation performed successfully" << std::endl;}reset_sam = true;}auto main(int argc, char *argv[]) -> int{SCM scm;scm.asyncGetReaders("Ux410",print_readers_list);while ( !get_readers ) {boost::this_thread::sleep_for(boost::chrono::seconds(2));}scm.asyncResetSamSlot("Ux410", (dpySCM::SamSlot)1, result_sync_handler);while ( !reset_sam ) {boost::this_thread::sleep_for(boost::chrono::seconds(2));}reset_sam = false;scm.asyncResetSamSlot("Ux410", (dpySCM::SamSlot)2, result_sync_handler);while ( !reset_sam ) {boost::this_thread::sleep_for(boost::chrono::seconds(2));}return 0;} -
Read smart card example
Complete example for reading the blocks/pages 4 and 5 for a Mifare Classic or an Ultralight. It tries to set the keys if they have not been done before. It have been set a default keys 0x'FF'#include <dpy/scmApi.h>#include <iostream>static SCM scm;dpySCM::DeviceKeys set_keys(std::string deviceid){dpySCM::DeviceKeys keygroup;std::cout << "\rSetting keys to: " << deviceid << std::endl;keygroup.deviceId = deviceid;dpySCM::KeyGroup keygroup1;keygroup1.priority = 0;dpySCM::Key keys_g1;keys_g1.index = 0;keys_g1.keytype = dpySCM::KEY_A;keys_g1.keys = "FFFFFFFFFFFF";keygroup1.key.push_back(keys_g1);keys_g1.index = 1;keygroup1.key.push_back(keys_g1);keys_g1.index = 2;keygroup1.key.push_back(keys_g1);keys_g1.index = 3;keygroup1.key.push_back(keys_g1);keygroup.keys.push_back(keygroup1);return keygroup;}void print_readers_list(boost::system::error_code& ec, const dpySCM::DeviceReaderList& deviceReaderList){if (ec.value() == 0) {std::cout << "\rSmart Card Manager '" << deviceReaderList.deviceId << "' reader list:" << std::endl;for (std::vector<std::string>::size_type i = 0; i != deviceReaderList.readers.size(); i++) {std::cout << deviceReaderList.readers[i].socket << ", ";std::cout << deviceReaderList.readers[i].samuid << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}}void confirmation_handler_function(boost::system::error_code& ec){if (ec.value() == 0) {std::cout << "\rSmart Card Manager sets key successfully'" << std::endl;} else {std::cout << "\rError : " << ec.message() << std::endl;}}void print_keys(boost::system::error_code& ec, dpySCM::DeviceKeys deviceKeys){if (ec.value() == 0) {if (deviceKeys.keys.size() > 0) {std::cout << "\rSmart Card Manager gets key successfully for: '" << deviceKeys.deviceId << std::endl;std::vector<dpySCM::KeyGroup>::iterator it;std::cout << "\rKeys with priority: " << it->priority << std::endl;std::vector<dpySCM::Key>::iterator it2;for (it2 = it->key.begin(); it2 != it->key.end(); ++it2) {std::cout << "\rKey index: " << it2->index << " value: " << it2->keys << std::endl;}}} else {/* ADD KEYS FOR THIS DEVICE CONNECTED */scm.asyncAddKeys(set_keys(deviceKeys.deviceId), confirmation_handler_function);}} else {std::cout << "\rError : " << ec.message() << std::endl;}}{if (ec.value() == 0) {std::cout << "\rSmart Card Manager device list: " << std::endl;for (std::vector<std::string>::size_type i = 0; i != rDevice.device.size(); i++) {/* GET THE KEYS FOR THIS DEVICE */scm.asyncGetKeys(rDevice.device[i], print_keys);/* GET READERS FOR THIS DEVICE */std::cout << "\r- " << rDevice.device[i] << std::endl;scm.asyncGetReaders(rDevice.device[i], print_readers_list);}} else {std::cout << "\rError : " << ec.message() << std::endl;}}void print_transaction(boost::system::error_code& ec, dpySCM::TransactionDevice TransactionDevice){if (ec.value() == 0) {std::cout << "\rSmart Card Manager device: " << TransactionDevice.deviceId << std::endl;std::vector<dpySCM::CardOperation>::iterator it;std::cout << "\rUID: " << it->uid << "\rIndex: " << it->index << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}}void new_card_event(boost::system::error_code& ec, const std::string& deviceId, dpySCM::CardEvent cardEvent){if (ec.value() == 0) {std::cout << "\rNew card available: " << cardEvent.cardinfo.uid << " in the reader: " << cardEvent.cardinfo.readerName << " of device: " << deviceId << std::endl;/* -------------------- Synchronous request ---------------------------------- */std::list<dpySCM::Data> dataList;dpySCM::Data data;data.index = 4;dataList.push_back(data);data.index = 5;dataList.push_back(data);if (ec.value() == 0) {std::list<dpySCM::Data>::iterator it;for (it = dataList.begin(); it != dataList.end(); ++it) {std::cout << "\rThe index: " << it->index << " has the value: " << it->buffer << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}/* ----------------------------------------------------------------------------- *//* -------------------- Asynchronous request -----------------------------------dpySCM::TransactionDevice operationDevice;operationDevice.deviceId = deviceId;dpySCM::CardOperation operation;operation.uid = cardEvent.cardinfo.uid;operation.operationType = dpySCM::READ;operation.index = 4;operation.priority = 0;operationDevice.operation.push_back(operation);scm.asyncCardOperation(operationDevice, print_transaction);------------------------------------------------------------------------------- */}} else {std::cout << "\rError : " << ec.message() << std::endl;}}int main(int argc, char *argv[]){scm.asyncGetDevices(print_device_list);scm.newCardEvent_S(new_card_event);while (1){}} -
APDU exchange with SAM
Complete example for exchanging APDUs, in this case using a SAM card. Before sending any command, the program ask for SAMs connected, afterwards, if is given the example for synchronous and asynchronous operations.#include <dpy/scmApi.h>#include <iostream>volatile bool waiting = true;static SCM scm;void print_transaction(boost::system::error_code& ec, dpySCM::TransactionDevice TransactionDevice){if (ec.value() == 0) {std::cout << "\rSmart Card Manager device: " << TransactionDevice.deviceId << std::endl;std::vector<dpySCM::CardOperation>::iterator it;dpySCM::ApduRxData apduRxData = it->rxData;std::cout << "\rUID: " << it->uid << "\tSW1: " << apduRxData.sw1 << "\tSW2: " << apduRxData.sw2 <<"\tResult: " << apduRxData.rxData << std::endl;}} else {std::cout << "\rError : " << ec.message() << std::endl;}}void print_readers_list(boost::system::error_code& ec, const dpySCM::DeviceReaderList& deviceReaderList){if (ec.value() == 0) {std::cout << "\rSmart Card Manager '" << deviceReaderList.deviceId << "' reader list:" << std::endl;std::list<dpySCM::ApduTxData> apduTx;dpySCM::ApduTxData apduTxData;apduTxData.class_instruction = 0x90;apduTxData.instruction = 0x10;apduTxData.param1 = 0x00;apduTxData.param2 = 0x00;apduTxData.expectedResponseLen = 0x14;apduTx.push_back(apduTxData);for (std::vector<std::string>::size_type i = 0; i != deviceReaderList.readers.size(); i++) {std::cout << deviceReaderList.readers[i].socket << ", ";std::cout << deviceReaderList.readers[i].samuid << std::endl;if ((deviceReaderList.readers[i].deviceid.find("SAMREADER") != std::string::npos) && (deviceReaderList.readers[i].samuid != "NA")) {/* -------------------------------------------- Synchronous request -----------------------------------------------------------std::list<dpySCM::ApduRxData> apduRx;error = scm.apduExchange(deviceReaderList.deviceId, deviceReaderList.readers[i].samuid, apduTx, apduRx);if (error.value() == 0) {std::list<dpySCM::ApduRxData>::iterator it;for (it = apduRx.begin(); it != apduRx.end(); it++) {char32_t SW1 = it->sw1;char32_t SW2 = it->sw2;std::string rxRawData = it->rxData;std::cout << "\rSW1: " << SW1 << "\tSW2: " << SW2 << "\tResult: " << rxRawData << std::endl;}} else {std::cout << "\rError while exchanging the APDU. Error: [" << error.value() << "] "<< ec.message() << std::endl;}------------------------------------------------------------------------------------------------------------------------------- *//* -------------------------------------------- Asynchronous request ------------------------------------------------------------- */dpySCM::TransactionDevice operationDevice;dpySCM::CardOperation operation;operation.operationType = dpySCM::APDU;operation.priority = 0;operation.txData = apduTxData;operationDevice.operation.push_back(operation);scm.asyncCardOperation(operationDevice, print_transaction);/* ---------------------------------------------------------------------------------------------------------------------------------- */} else {std::cout << "\rThere is not a SAM reader" << std::endl;}}} else {std::cout << "\rError : " << ec.message() << std::endl;}//waiting = false;}{if (ec.value() == 0) {std::cout << "\rSmart Card Manager device list: " << std::endl;for (std::vector<std::string>::size_type i = 0; i != rDevice.device.size(); i++) {/* GET READERS FOR THIS DEVICE */std::cout << "\r- " << rDevice.device[i] << std::endl;scm.asyncGetReaders(rDevice.device[i], print_readers_list);}} else {std::cout << "\rError : " << ec.message() << std::endl;}}int main(int argc, char *argv[]){scm.asyncGetDevices(print_device_list);while (waiting){}} -
Play profile example
#include <dpy/scmApi.h>#include <iostream>void result_sync_handler(boost::system::error_code ec){if (ec) {std::cout << "\rError : " << ec.message() << std::endl;} else {std::cout << "\rSynchronous operation performed successfully" << std::endl;}}int main(int argc, char *argv[]){SCM scm;scm.asyncPlayProfile("verifone", "Default_OK", result_sync_handler);} -
Pass-through example
Example for sending commands synchronously via pass-through whenever a new card is added.#include <dpy/scmApi.h>#include <iostream>volatile bool waiting = true;static SCM scm;void card_event_handler(boost::system::error_code &ec, const std::string &deviceId, dpySCM::CardEvent cardEvent){if (ec.value() == 0) {//Send a pass through command to the card that has been detectedstd::cout << "Card with UID " << cardEvent.cardinfo.uid << " has been detected at device with id " << deviceId << ", reader " << cardEvent.cardinfo.readerName << std::endl;//Create the command or commands that want to be sentdpySCM::Command cmd_one;cmd_one.inRawData = "A50101000000";dpySCM::Command cmd_two;cmd_two.inRawData = "3901";//Fill the PassThrough structure containing the querydpySCM::PassThrough passThroughCmd;passThroughCmd.commands.push_back(cmd_one);passThroughCmd.commands.push_back(cmd_two);//Make a synchronous passThrough querystd::cout << "Sending command [" << cmd_one.inRawData << "] and command [" << cmd_two.inRawData << "]" << std::endl;boost::system::error_code error_code = scm.passThrough(deviceId, passThroughCmd);if (error_code.value() == 0) {std::cout << "Pass through query was successful" << std::endl;int i = 1;std::cout << "\tCommand [" << i << "] " << std::endl;if (command.errorCode == 0) {std::cout << "\t\tPass through command was processed correctly. Command response: " << std::endl;std::cout << "\t\tBuffer is [" << command.outRawData << "]" << std::endl;} else {std::cout << "\t\tPass through command could not be processed, error " << command.errorCode << std::endl;}i++;std::cout << "\t\t-------------- " << std::endl;}} else {std::cout << "Pass through command error " << ec.message() << std::endl;}} else {std::cout << "Card with UID " << cardEvent.cardinfo.uid << " has been removed from device " << deviceId << std::endl;}} else {std::cout << "Error " << ec.message() << std::endl;}}int main(int argc, char *argv[]){//Listen to card eventsscm.newCardEvent_S(card_event_handler);std::cout << "Waiting for card events ... " << std::endl;while (waiting) {}}