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) {}} -
Observer Pattern Example
Demonstrating how to use the observer pattern to subscribe to Smart Card events.#include <dpyError.h>#include <dpy/scmApi.h>#include <iostream>#include <boost/bind.hpp>#include <boost/bind/placeholders.hpp>#include <boost/thread.hpp>#include <type_traits>#include <variant>#include <mutex>#include <condition_variable>class App: public IsmartCardReaderObserver, public IsmartCardDeviceObserver, public IsmartCardDeviceListObserver{private:SCM scm;public:App() = default;~App() = default;void start(){scm.subscribeReaderEvent(this);scm.subscribeDeviceListEvent(this);scm.subscribeDeviceEvent(this);}void finish(){scm.unsubscribeReaderEvent(this);scm.unsubscribeDeviceListEvent(this);scm.unsubscribeDeviceEvent(this);}void newSmartCard(boost::system::error_code& ec, const std::string& deviceId, dpySCM::CardEvent cardEvent) override{if (ec.value() == 0) {} else {}} else {std::cout << "\rError : " << ec.message() << std::endl;}}void chargeResult(boost::system::error_code& ec, dpySCM::DeviceChargeResult deviceChargeResult) override{std::cout << "\rNew charge result" << std::endl;}void deviceListEvent(boost::system::error_code& ec, const std::string& deviceId, dpySCM::Event deviceEvent) override{std::cout << "\r Device list notification" << std::endl;}void notifyPciReboot(boost::system::error_code& ec, dpySCM::DevicePciRebootTime& devicePciRebootTime) override{std::cout << "\r PCI Notification" << std::endl;}void newUpgradeStatus(boost::system::error_code& ec, dpySCM::DeviceUpgradeStatus& deviceUpgradeStatus) override{std::cout << "\r Upgrade status notification" << std::endl;}};auto main(int argc, char *argv[]) -> int{App app;app.start();std::cout << "\r Subscribe to events" << std::endl;boost::this_thread::sleep_for(boost::chrono::seconds(30));std::cout << "\r Unsubscribe to events" << std::endl;boost::this_thread::sleep_for(boost::chrono::seconds(30));std::cout << "\r Finish program" << std::endl;return [](){return 0;}();} -
Manual Authentication Example
Demonstrating how to authenticate, read and write using the manual mode#include <dpy/scmApi.h>#include <iostream>#include <boost/thread/thread.hpp>static SCM scm;static std::list<dpySCM::Data> readDataList;static std::list<dpySCM::Data> writeDataList;static std::list<dpySCM::Data> authDataList;void dataInitialization(){/*********** AUTHENTICATION ********************/authDataList.clear();dpySCM::Data authData;// Sector 4authData.index = 4;authData.buffer = "FFFFFFFFFFFF";authData.keyTypeUsed = dpySCM::KeyType::KEY_A;authDataList.push_back(authData);/*********** READING ********************/readDataList.clear();dpySCM::Data readData;// Sector 4readData.index = 16;readDataList.push_back(readData);readData.index = 17;readDataList.push_back(readData);readData.index = 18;readDataList.push_back(readData);/*********** WRITING ********************/writeDataList.clear();dpySCM::Data writeData;// Sector 4writeData.index = 16;writeData.buffer = "0A0A000000000000000000000E0E0B0B";writeDataList.push_back(writeData);writeData.index = 18;writeData.buffer = "0A0A000000000000000000000E0E0B0A";writeDataList.push_back(writeData);}void new_card_event(boost::system::error_code& ec, const std::string& deviceId, dpySCM::CardEvent cardEvent){dataInitialization();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 ---------------------------------- */if (ec.value() == 0){std::cout << "\nSuccessful Authentication." << std::endl;if (ec.value() == 0) {std::cout << "\nSuccessful first read." << std::endl;std::list<dpySCM::Data>::iterator it;for (it = readDataList.begin(); it != readDataList.end(); ++it) {std::cout << "\rThe index: " << it->index << " has the value: " << it->buffer << std::endl;}if (ec.value() == 0) {std::cout << "\nSuccessful write." << std::endl;std::list<dpySCM::Data>::iterator it;for (it = writeDataList.begin(); it != writeDataList.end(); ++it) {std::cout << "\rThe index: " << it->index << " has the value: " << it->buffer << std::endl;}if (ec.value() == 0) {std::cout << "\nSuccessful second read." << std::endl;std::list<dpySCM::Data>::iterator it;for (it = readDataList.begin(); it != readDataList.end(); ++it) {std::cout << "\rThe index: " << it->index << " has the value: " << it->buffer << std::endl;}} else {std::cout << "\rError second reading: " << ec.message() << std::endl;}} else {std::cout << "\rError Writing: " << ec.message() << std::endl;}} else {std::cout << "\rError first reading: " << ec.message() << std::endl;}}else{std::cout << "\rAuthentication error: " << ec.message() << std::endl;}}} else {std::cout << "\rError : " << ec.message() << std::endl;}}int main(){std::cout << "==== ==== ==== Manual Authentication Example: ==== ==== ====" << std::endl;std::cout << "Subscribing to new card events...\n" << std::endl;scm.newCardEvent_S(new_card_event);while (1) {boost::this_thread::sleep_for(boost::chrono::milliseconds(100));}} -
Ultra Light Counter Operations Example
Demonstrating how to read and increment a counter on a MF Ultra Light Card.#include <dpy/scmApi.h>#include <iostream>static SCM scm;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;dpySCM::UltraLightCounter _counter;_counter.counter = 2;ec = scm.getULCounter(deviceId, _counter);if (ec.value() != 0){std::cout << "\nError Getting Ultralight: " << ec.message() << std::endl;return;}std::cout << "\nCounter [" << std::to_string(_counter.counter) << "] value: " << std::to_string(_counter.value) << std::endl;dpySCM::UltraLightCounter _counter2;_counter2.counter = 2;_counter2.value = 2;ec = scm.incrementULCounter(deviceId, _counter2);if (ec.value() != 0){std::cout << "\nError Increment Ultralight Counter [" << std::to_string(_counter2.counter) << "] in " << std::to_string(_counter2.value) <<". Error: " << ec.message() << std::endl;} else {std::cout << "\nCorrect Increment Ultralight Counter [" << std::to_string(_counter2.counter) << "] in " << std::to_string(_counter2.value) << std::endl;}dpySCM::UltraLightCounter _counter3;_counter3.counter = 2;ec = scm.getULCounter(deviceId, _counter3);if (ec.value() != 0){std::cout << "\nError Getting Ultralight Counter: [" << std::to_string(_counter2.counter) << "]. Error: " << ec.message() << std::endl;return;}std::cout << "\nCounter [" << std::to_string(_counter3.counter) << "] value: " << std::to_string(_counter3.value) << std::endl;}}} else {std::cout << "\rError : " << ec.message() << std::endl;}}int main(){std::cout << "==== ==== ==== Ultra Light Counter Operations Example ==== ==== ====" << std::endl;std::cout << "Subscribing to new card events...\n" << std::endl;scm.newCardEvent_S(new_card_event);while (1) {}return 0;} -
Restore and Transfer Block Example
Demonstrating how to restore and transfer blocks in a MF Classic Card.#include <dpy/scmApi.h>#include <iostream>volatile bool waiting = true;static SCM scm;void read_block(boost::system::error_code& ec, std::string deviceId, std::string uid, std::list<dpySCM::DataBlock> content){std::list<dpySCM::Data> data_list;for (auto db : content) {dpySCM::Data data;data.index = db.index;data.priority = db.priority;data_list.push_back(data);}ec = scm.read(deviceId, uid, data_list);for (auto const &data : data_list) {if (ec.value() != 0) {std::cout << "\rError on read block" << std::endl;} else {std::cout << "\rValue readed: " << data.buffer << std::endl;}}}void write_block(boost::system::error_code& ec, std::string deviceId, std::string uid, std::list<dpySCM::Data> data_list){ec = scm.write(deviceId, uid, data_list);for (auto const &data : data_list) {if (ec.value() != 0) {std::cout << "\rError on write block" << std::endl;} else {std::cout << "\rValue written: " << data.buffer << std::endl;}}}boost::system::error_code ensure_correct_block_format(const std::string& _deviceId, const std::string& _uid){boost::system::error_code ec;std::list<dpySCM::Data> data_list;dpySCM::Data data;data.index = 16;data.priority = 3;/*// ===== ===== ===== ===== ===== ===== Useful information about a block format ===== ===== ===== ===== ===== =====// Source: https://stackoverflow.com/questions/72431616/android-nfc-mifare-classic-restore-and-transfer-not-working//// Byte number: | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 | 13 | 14 | 15 |// Description: | value | ~value | value | adr | ~adr | adr | ~adr |//// Value in Little Endian//// Used in this example// (1) Value 255 - block 16// Byte number: | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 | 13 | 14 | 15 |// Description: | 255 | ~255 | 255 | 16 | ~16 | 16 | ~16 |// Hex value: | FF 00 00 00 | 00 FF FF FF | FF 00 00 00 | 10 | EF | 10 | EF |// (2) Value 204 - block 16// Byte number: | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 | 12 | 13 | 14 | 15 |// Description: | 204 | ~204 | 204 | 16 | ~16 | 16 | ~16 |// Hex value: | CC 00 00 00 | 33 FF FF FF | CC 00 00 00 | 10 | EF | 10 | EF |*/data_list.push_back(data);write_block(ec, _deviceId, _uid, data_list);return ec;}void new_card_event(boost::system::error_code& ec, const std::string& deviceId, dpySCM::CardEvent cardEvent){if (ec.value() == 0) {std::cout << "\n\rNew card available: " << cardEvent.cardinfo.uid << " in the reader: " << cardEvent.cardinfo.readerName << " of device: " << deviceId << std::endl;if (ec.value() != 0) {std::cout << "\rError while formatting block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "\r(1) Block formatted correctly!" << std::endl;std::cout << "(2) Reading block first time. Original value:" << std::endl;std::list<dpySCM::DataBlock> contents;db.index = 16;db.priority = 3;contents.push_back(db);if (ec.value() != 0) {return;}std::cout << "(3) Saving block contain..." << std::endl;if (ec.value() == 0) {} else {std::cout << "\rError while executing restoreBlock. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(4) Overwriting block contain..." << std::endl;std::list<dpySCM::Data> data_list;dpySCM::Data data;data.index = 16;data.priority = 3;data_list.push_back(data);if (ec.value() != 0) {return;}std::cout << "(5) Transfering saved block contain..." << std::endl;if (ec.value() == 0) {} else {std::cout << "\rError while executing transfer block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(6) Reading block again. Expected original value:" << std::endl;if (ec.value() != 0) {return;}}} else {std::cout << "\rError : " << ec.message() << std::endl;}waiting = false;}int main(){std::cout << "==== ==== ==== Restore and Transfer Block Example ==== ==== ====" << std::endl;std::cout << "PRECONDITIONS: The correct keys must be saved on the Smart Card Device" << std::endl;std::cout << "\rPlace the card in the reader...\n\n" << std::endl;scm.newCardEvent_S(new_card_event);while (waiting){}return 0;} -
Increment, Decrement and Transfer Block Example
Demonstrating how to increment, decrement and transfer blocks in a MF Classic Card#include <dpy/scmApi.h>#include <iostream>volatile bool waiting = true;static SCM scm;void read_block(boost::system::error_code& ec, std::string deviceId, std::string uid, std::list<dpySCM::DataBlock> content){std::list<dpySCM::Data> data_list;for (auto db : content) {dpySCM::Data data;data_list.push_back(data);}ec = scm.read(deviceId, uid, data_list);for (auto const &data : data_list) {if (ec.value() != 0) {std::cout << "\rError on read block" << std::endl;} else {std::cout << "\rValue readed: " << data.buffer << std::endl;}}}void write_block(boost::system::error_code& ec, std::string deviceId, std::string uid, std::list<dpySCM::DataBlock> content){std::list<dpySCM::Data> data_list;for (auto db : content) {dpySCM::Data data;data_list.push_back(data);}ec = scm.write(deviceId, uid, data_list);for (auto const &data : data_list) {if (ec.value() != 0) {std::cout << "\rError on write block" << std::endl;} else {std::cout << "\rValue written: " << data.buffer << 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;std::list<dpySCM::DataBlock> contents;db.index = 16;db.priority = 3;db.value = 5;contents.push_back(db);std::cout << "(1) Original value: " << std::endl;if (ec.value() != 0) {return;}if (ec.value() == 0) {} else {std::cout << "\rError while executing increment block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(2) Value updated: " << std::endl;if (ec.value() != 0) {return;}contents.clear();db.index = 16;db.priority = 3;db.value = 2;contents.push_back(db);if (ec.value() == 0) {} else {std::cout << "\rError while executing decrement only block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(3) Value updated in buffer, same value readed in step 2: " << std::endl;if (ec.value() != 0) {return;}if (ec.value() == 0) {} else {std::cout << "\rError while executing transfer block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(4) Value updated: " << std::endl;if (ec.value() != 0) {return;}contents.clear();db.index = 16;db.priority = 3;db.value = 2;contents.push_back(db);if (ec.value() == 0) {} else {std::cout << "\rError while executing increment block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(5) Value updated: " << std::endl;if (ec.value() != 0) {return;}contents.clear();db.index = 16;db.priority = 3;db.value = 4;contents.push_back(db);if (ec.value() == 0) {} else {std::cout << "\rError while executing decrement only block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(6) Value updated in buffer, same value readed in step 5: " << std::endl;if (ec.value() != 0) {return;}if (ec.value() == 0) {} else {std::cout << "\rError while executing transfer block. Error: [" << ec.value() << "] "<< ec.message() << std::endl;return;}std::cout << "(7) Value updated: " << std::endl;if (ec.value() != 0) {return;}}} else {std::cout << "\rError : " << ec.message() << std::endl;}waiting = false;}int main(){std::cout << "==== ==== ==== Increment and Transfer Block Example ==== ==== ====" << std::endl;std::cout << "PRECONDITIONS: " << std::endl;std::cout << "\t 1 - The correct keys must be saved on the Smart Card Device" << std::endl;std::cout << "\t 2 - Block 16 must be in the correct format to block operations" << std::endl;std::cout << "\rPlace the card in the reader...\n\n" << std::endl;scm.newCardEvent_S(new_card_event);while (waiting){}return 0;}