Browse Source

refs #1 Syncronizing with release commit: 04e5899d3e (2)

qt5
parent
commit
2f2b2fb527
38 changed files with 5212 additions and 0 deletions
  1. +498
    -0
      3.0/src/includes/Hardware/CardReaders/EMVTagData.h
  2. +1
    -0
      3.0/src/includes/Hardware/Protocols/FR/AFPFR.h
  3. +6
    -0
      3.0/src/interface/modern/info_popup2.ini
  4. +91
    -0
      3.0/src/interface/modern/info_popup2.qml
  5. +380
    -0
      3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReader.cpp
  6. +65
    -0
      3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReader.h
  7. +202
    -0
      3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderConstants.h
  8. +16
    -0
      3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderDataTypes.h
  9. +24
    -0
      3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderModelData.h
  10. +156
    -0
      3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVAdapter.cpp
  11. +61
    -0
      3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVAdapter.h
  12. +45
    -0
      3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVConstants.h
  13. +143
    -0
      3.0/src/modules/Hardware/Cardreaders/src/EMV/TLV.cpp
  14. +75
    -0
      3.0/src/modules/Hardware/Cardreaders/src/EMV/TLV.h
  15. +124
    -0
      3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechCallbacks.cpp
  16. +25
    -0
      3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechCallbacks.h
  17. +81
    -0
      3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechModelData.h
  18. +329
    -0
      3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechReader.cpp
  19. +79
    -0
      3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechReader.h
  20. +941
    -0
      3.0/src/modules/Hardware/FR/src/MStar/Online/AFPFR.cpp
  21. +125
    -0
      3.0/src/modules/Hardware/FR/src/MStar/Online/AFPFR.h
  22. +250
    -0
      3.0/src/modules/Hardware/FR/src/MStar/Online/AFPFRConstants.h
  23. +135
    -0
      3.0/src/modules/Hardware/FR/src/MStar/Online/AFPFRDataTypes.h
  24. +39
    -0
      3.0/src/modules/Hardware/FR/src/MStar/Online/ModelData.h
  25. +128
    -0
      3.0/src/modules/Hardware/Protocols/FR/AFP/AFPFRProtocol.vcxproj
  26. +28
    -0
      3.0/src/modules/Hardware/Protocols/FR/AFP/AFPFRProtocol.vcxproj.filters
  27. +177
    -0
      3.0/src/modules/Hardware/Protocols/FR/AFP/src/AFPFR.cpp
  28. +30
    -0
      3.0/src/modules/Hardware/Protocols/FR/AFP/src/AFPFR.h
  29. +35
    -0
      3.0/src/modules/Hardware/Protocols/FR/AFP/src/AFPFRConstants.h
  30. +187
    -0
      3.0/src/plugins/NativeWidgets/ServiceMenu/src/GUI/MessageBox/MessageBox.cpp
  31. +98
    -0
      3.0/src/plugins/NativeWidgets/ServiceMenu/src/GUI/MessageBox/MessageBox.h
  32. +100
    -0
      3.0/src/plugins/NativeWidgets/ServiceMenu/src/GUI/MessageBox/MessageWindow.cpp
  33. +39
    -0
      3.0/src/plugins/NativeWidgets/ServiceMenu/src/GUI/MessageBox/MessageWindow.h
  34. +201
    -0
      3.0/src/plugins/NativeWidgets/ServiceMenu/src/GUI/MessageBox/MessageWindow.ui
  35. +109
    -0
      3.0/src/plugins/Payments/Cyberplat/src/DealerLocalData.cpp
  36. +34
    -0
      3.0/src/plugins/Payments/Cyberplat/src/DealerLocalData.h
  37. +91
    -0
      3.0/src/runtimes/ru/common/receipts/data/receipts/payment_book_cyberplat_changeback.xml
  38. +64
    -0
      3.0/src/runtimes/ru/common/receipts/data/receipts/payment_reserve_master.xml

+ 498
- 0
3.0/src/includes/Hardware/CardReaders/EMVTagData.h View File

@@ -0,0 +1,498 @@
/* @file Данные тегов EMV. */

#pragma once

#include "Hardware/Common/Specifications.h"

//--------------------------------------------------------------------------------
namespace CEMVTags
{
const int MSREquivalentData = 0xDFEF4D;

class CData : public CDescription<int>
{
public:
CData()
{
append( 0x42, "Issuer Identification Number (IIN)");
append( 0x4F, "Application Identifier (ADF Name)");
append( 0x50, "Application Label");
append( 0x52, "Command to perform");
append( 0x56, "Track 1 Data");
append( 0x57, "Track 2 Equivalent Data");
append( 0x5A, "Application Primary Account Number (PAN)");
append( 0x5D, "Deleted (see 9D)");
append( 0x6F, "File Control Information (FCI) Template");
append( 0x61, "Application Template");
append( 0x62, "File Control Parameters (FCP) Template");
append( 0x70, "READ RECORD Response Message Template");
append( 0x71, "Issuer Script Template 1");
append( 0x72, "Issuer Script Template 2");
append( 0x73, "Directory Discretionary Template");
append( 0x77, "Response Message Template Format 2");
append( 0x80, "Response Message Template Format 1");
append( 0x81, "Amount, Authorised (Binary)");
append( 0x82, "Application Interchange Profile (AIP)");
append( 0x83, "Command Template");
append( 0x84, "Dedicated File (DF) Name");
append( 0x86, "Issuer Script Command");
append( 0x87, "Application Priority Indicator");
append( 0x88, "Short File Identifier (SFI)");
append( 0x89, "Authorisation Code");
append( 0x8A, "Authorization Response Code");
append( 0x8A, "Authorisation Response Code (ARC)");
append( 0x8C, "Card Risk Management Data Object List 1 (CDOL1)");
append( 0x8D, "Card Risk Management Data Object List 2 (CDOL2)");
append( 0x8E, "Cardholder Verification Method (CVM) List");
append( 0x8F, "Certification Authority Public Key Index (PKI)");
append( 0x90, "Issuer Public Key Certificate");
append( 0x91, "Issuer Authentication Data");
append( 0x92, "Issuer Public Key Remainder");
append( 0x93, "Signed Application Data");
append( 0x94, "Application File Locator (AFL)");
append( 0x95, "Terminal Verification Results (TVR)");
append( 0x97, "Transaction Certificate Data Object List (TDOL)");
append( 0x98, "Transaction Certificate (TC) Hash Value");
append( 0x99, "Transaction Personal Identification Number (PIN) Data");
append( 0x99, "Transaction Personal Identification Number (PIN) Data");
append( 0x98, "Transaction Certificate (TC) Hash Value");
append( 0x9A, "Transaction Date (YYMMDD )");
append( 0x9A, "Transaction Date");
append( 0x9B, "Transaction Status Information");
append( 0x9B, "Transaction Status Information");
append( 0x9C, "Transaction Type");
append( 0x9C, "Transaction Type");
append( 0x9D, "Directory Definition File (DDF) Name");
append( 0xA5, "File Control Information (FCI) Proprietary Template");
append( 0xC3, "Card issuer action code -decline");
append( 0xC4, "Card issuer action code -default");
append( 0xC5, "Card issuer action code online");
append( 0xC6, "PIN Try Limit");
append( 0xC7, "CDOL 1 Related Data Length");
append( 0xC8, "Card risk management country code");
append( 0xC9, "Card risk management currency code");
append( 0xCA, "Lower cummulative offline transaction amount");
append( 0xCB, "Upper cumulative offline transaction amount");
append( 0xCD, "Card Issuer Action Code (PayPass) – Default");
append( 0xCE, "Card Issuer Action Code (PayPass) – Online");
append( 0xCF, "Card Issuer Action Code (PayPass) – Decline");
append( 0xD1, "Currency conversion table");
append( 0xD2, "Integrated Data Storage Directory (IDSD)");
append( 0xD3, "Additional check table");
append( 0xD5, "Application Control");
append( 0xD6, "Default ARPC response code");
append( 0xD7, "Application Control (PayPass)");
append( 0xD8, "AIP (PayPass)");
append( 0xD9, "AFL (PayPass)");
append( 0xDA, "Static CVC3-TRACK1");
append( 0xDB, "Static CVC3-TRACK2");
append( 0xDC, "IVCVC3-TRACK1");
append( 0xDD, "IVCVC3-TRACK2");
append( 0x5F20, "Cardholder Name");
append( 0x5F24, "Application Expiration Date");
append( 0x5F28, "Issuer Country Code");
append( 0x5F2A, "Transaction Currency Code (Default: 08 40)");
append( 0x5F2D, "Language Preference");
append( 0x5F30, "Service Code");
append( 0x5F34, "Application Primary Account Number (PAN) Sequence Number (PSN)");
append( 0x5F36, "Transaction Currency Exponent");
append( 0x5F3C, "Transaction Reference Currency Code");
append( 0x5F3D, "Transaction Reference Currency Exponent");
append( 0x5F50, "Issuer URL");
append( 0x5F53, "International Bank Account Number (IBAN)");
append( 0x5F54, "Bank Identifier Code (BIC)");
append( 0x5F55, "Issuer Country Code (alpha2 format)");
append( 0x5F56, "Issuer Country Code (alpha3 format)");
append( 0x5F57, "Account Type Selection");
append( 0x9F01, "Acquirer Identifier");
append( 0x9F02, "Amount, Authorized (Numeric)");
append( 0x9F03, "Amount, Other (Numeric)");
append( 0x9F04, "Amount, Other (Binary)");
append( 0x9F05, "Application Discretionary Data");
append( 0x9F06, "Application Identifier (AID) – terminal");
append( 0x9F07, "Application Usage Control (AUC)");
append( 0x9F08, "Application Version Number");
append( 0x9F09, "Application Version Number (Default: 00 02 )");
append( 0x9F0B, "Cardholder Name Extended");
append( 0x9F0D, "Issuer Action Code - Default");
append( 0x9F0E, "Issuer Action Code - Denial");
append( 0x9F0F, "Issuer Action Code - Online");
append( 0x9F10, "Issuer Application Data (IAD)");
append( 0x9F11, "Issuer Code Table Index");
append( 0x9F12, "Application Preferred Name");
append( 0x9F13, "Last Online Application Transaction Counter (ATC) Register");
append( 0x9F14, "Lower Consecutive Offline Limit");
append( 0x9F15, "Merchant Category Code");
append( 0x9F16, "Merchant Identifier");
append( 0x9F17, "Personal Identification Number (PIN) Try Counter");
append( 0x9F18, "Issuer Script Identifier");
append( 0x9F19, "Deleted (see 9F49)");
append( 0x9F1A, "Terminal Country Code");
append( 0x9F1B, "Terminal Floor Limit");
append( 0x9F1C, "Terminal Identification");
append( 0x9F1D, "Terminal Risk Management Data");
append( 0x9F1E, "Interface Device (IFD) Serial Number");
append( 0x9F1F, "Track 1 Discretionary Data");
append( 0x9F20, "Track 2 Discretionary Data");
append( 0x9F21, "Transaction Time (HHMMSS )");
append( 0x9F22, "Certification Authority Public Key Index");
append( 0x9F23, "Upper Consecutive Offline Limit");
append( 0x9F26, "Application Cryptogram (AC)");
append( 0x9F27, "Cryptogram Information Data (CID)");
append( 0x9F29, "Extended Selection");
append( 0x9F2A, "Kernel Identifier");
append( 0x9F2D, "Integrated Circuit Card (ICC) PIN Encipherment Public Key Certificate");
append( 0x9F2E, "Integrated Circuit Card (ICC) PIN Encipherment Public Key Exponent");
append( 0x9F2F, "Integrated Circuit Card (ICC) PIN Encipherment Public Key Remainder");
append( 0x9F32, "Issuer Public Key Exponent");
append( 0x9F33, "Terminal Capabilities (see below)");
append( 0x9F34, "Cardholder Verification Method (CVM) Results");
append( 0x9F35, "Terminal Type (see below)");
append( 0x9F36, "Application Transaction Counter (ATC)");
append( 0x9F37, "Unpredictable Number");
append( 0x9F38, "Processing Options Data Object List (PDOL)");
append( 0x9F39, "POS Entry Mode (Default: 07)");
append( 0x9F3A, "Amount, Reference Currency");
append( 0x9F3B, "Application Reference Currency");
append( 0x9F3C, "Transaction Reference Currency Code");
append( 0x9F3D, "Transaction Reference Currency Exponent");
append( 0x9F40, "Additional Terminal Capabilities (see below)");
append( 0x9F41, "Transaction Sequence Counter");
append( 0x9F42, "Application Currency Code");
append( 0x9F43, "Application Reference Currency Exponent");
append( 0x9F44, "Application Currency Exponent");
append( 0x9F45, "Data Authentication Code");
append( 0x9F46, "Integrated Circuit Card (ICC) Public Key Certificate");
append( 0x9F47, "Integrated Circuit Card (ICC) Public Key Exponent");
append( 0x9F48, "Integrated Circuit Card (ICC) Public Key Remainder");
append( 0x9F49, "Dynamic Data Authentication Data Object List (DDOL)");
append( 0x9F4A, "Static Data Authentication Tag List (SDA)");
append( 0x9F4B, "Signed Dynamic Application Data (SDAD)");
append( 0x9F4C, "ICC Dynamic Number");
append( 0x9F4D, "Log Entry");
append( 0x9F4E, "Merchant Name and Location");
append( 0x9F4E, "Merchant Name and Location");
append( 0x9F4F, "Log Format");
append( 0x9F50, "Offline Accumulator Balance");
append( 0x9F51, "Application Currency Code");
append( 0x9F52, "Application Default Action (ADA)");
append( 0x9F53, "Transaction Category Code");
append( 0x9F54, "DS ODS Card");
append( 0x9F55, "Geographic Indicator");
append( 0x9F56, "Issuer Authentication Indicator");
append( 0x9F57, "Issuer Country Code");
append( 0x9F58, "Consecutive Transaction Counter Limit (CTCL)");
append( 0x9F59, "Consecutive Transaction Counter Upper Limit (CTCUL)");
append( 0x9F5A, "Application Program Identifier (Program ID)");
append( 0x9F5B, "Issuer Script Results");
append( 0x9F5C, "Magstripe Data Object List (MDOL)");
append( 0x9F5D, "Available Offline Spending Amount (AOSA)");
append( 0x9F5D, "Application Capabilities Information (ACI)");
append( 0x9F5E, "Consecutive Transaction International Upper Limit (CTIUL)");
append( 0x9F5E, "DS ID");
append( 0x9F5F, "DS Slot Availability");
append( 0x9F60, "CVC3 (Track1)");
append( 0x9F61, "CVC3 (Track2)");
append( 0x9F62, "PCVC3 (Track1)");
append( 0x9F64, "NATC (Track1)");
append( 0x9F65, "PCVC3 (Track2)");
append( 0x9F66, "PUNATC (Track2)");
append( 0x9F67, "NATC (Track2)");
append( 0x9F68, "Card Additional Processes");
append( 0x9F69, "UDOL");
append( 0x9F6A, "Unpredictable Number (Numeric)");
append( 0x9F6B, "Track 2 Data");
append( 0x9F6C, "Card Transaction Qualifiers (CTQ)");
append( 0x9F6D, "Mag-stripe Application Version Number (Reader)");
append( 0x9F6E, "Third Party Data");
append( 0x9F6E, "Terminal Transaction Capabilities");
append( 0x9F6F, "DS Slot Management Control");
append( 0x9F70, "Protected Data Envelope 1");
append( 0x9F71, "Protected Data Envelope 2");
append( 0x9F72, "Protected Data Envelope 3");
append( 0x9F73, "Protected Data Envelope 4");
append( 0x9F74, "Protected Data Envelope 5");
append( 0x9F75, "Unprotected Data Envelope 1");
append( 0x9F76, "Unprotected Data Envelope 2");
append( 0x9F77, "Unprotected Data Envelope 3");
append( 0x9F78, "Unprotected Data Envelope 4");
append( 0x9F79, "Unprotected Data Envelope 5");
append( 0x9F7A, "VLP Terminal Support Indicator");
append( 0x9F7B, "VLP Terminal Transaction Limit");
append( 0x9F7C, "Customer Exclusive Data (CED)");
append( 0x9F7D, "DS Summary 1");
append( 0x9F7F, "DS Unpredictable Number");
append( 0xBF0C, "File Control Information (FCI) Issuer Discretionary Data");
append( 0xBF50, "Visa Fleet - CDO");
append( 0xBF60, "Integrated Data Storage Record Update Template");
append( 0xDF01, "ApplePay VAS Protocol");
append( 0xDF02, "ApplePay VAS Failure Report");
append( 0xDF10, "Terminal Languages Supported");
append( 0xDF10, "Multi Language (Default: “enfr”)");
append( 0xDF11, "Enable Transaction Logging");
append( 0xDF13, "Terminal Action Code - Default");
append( 0xDF14, "Terminal Action Code - Denial");
append( 0xDF15, "Terminal Action Code - Online");
append( 0xDF17, "Threshold Value for Biased Random Selection");
append( 0xDF18, "Target Percentage to be Used for Random Selection");
append( 0xDF19, "Maximum Target Percentage to be used for Biased Random Selection");
append( 0xDF1F, "Last 4 digits of Primary Account Number (PAN)");
append( 0xDF21, "Issuer Script Results");
append( 0xDF22, "Force Online (1-Enable, 0-Disable)");
append( 0xDF25, "Default DDOL (1-Enable, 0-Disable)");
append( 0xDF26, "Revocation List Support (Default: Enable - 1)");
append( 0xDF27, "Exception File Support (Default: Disable - 0)");
append( 0xDF28, "Default TDOL");
append( 0xDF29, "Terminal Capabilities - CVM Required");
append( 0xDF2A, "Threshold Value for Biased Random Selection (Interac)");
append( 0xDF2B, "Maximum Target Percentage for Biased Random Selection (Interac)");
append( 0xDF2C, "Target Percentage for Random Selection (Interac)");
append( 0xDF30, "Track Data Source");
append( 0xDF31, "DD Card Track 1");
append( 0xDF32, "DD Card Track 2");
append( 0xDF33, "Interac Receipt Required");
append( 0xDF34, "TTK Customer - Firmware Version");
append( 0xDF40, "Message to be displayed by EMV Kernel on “PIN Try Limit Exceeded” condition");
append( 0xDF41, "Message to be displayed by EMV Kernel on “Last PIN Try” condition");
append( 0xDF42, "Message to be displayed by EMV Kernel on “Please Try Again” condition");
append( 0xDF43, "Message to be displayed by EMV Kernel on “Call Your Bank” condition");
append( 0xDF45, "GMEDS Secret Keys");
append( 0xDF46, "GMAD MIDs");
append( 0xDF47, "ISIS Read Cmd Data");
append( 0xDF48, "ISIS Write Data");
append( 0xDF49, "ISIS Transaction Data");
append( 0xDF4A, "TTK Customer - Current KSN of Data encryption Key");
append( 0xDF4B, "TTK Customer - MSR all track data");
append( 0xDF4C, "TTK Customer - Masked PAN");
append( 0xDF4D, "TTK Customer - Additional POS Info");
append( 0xDF4E, "Polling Options");
append( 0xDF4F, "TTK Customer - Fallback Reason");
append( 0xDF50, "Special Flow");
append( 0xDF51, "Amex Terminal Capability");
append( 0xDF52, "Transaction CVM");
append( 0xDF55, "RID");
append( 0xDF56, "Activate Trans for DESFireViVOComm Flows");
append( 0xDF57, "Reader Primary Language");
append( 0xDF57, "2nd usage: Remaining Candidates");
append( 0xDF58, "Reader Secondary Language");
append( 0xDF5A, "TLV Exclusion List");
append( 0xDF5B, "Terminal Entry Capability");
append( 0xDF5C, "RF Deactivate Period");
append( 0xDF5D, "D-PAS Issuer Script Response status");
append( 0xDF5E, "Transaction Timing Information");
append( 0xDF5F, "Encrypted PAN for remote PIN Pad");
append( 0xDF60, "Product ID");
append( 0xDF61, "Processor ID");
append( 0xDF61, "CVMRequiredLimit_JCBScheme");
append( 0xDF62, "Main Firmware Build ID");
append( 0xDF63, "CB Enhanced DDA Indicator (same block as DF03)");
append( 0xDF64, "CB Wave 2 CVM Requirements (same block as DF04)");
append( 0xDF65, "Build ID Num (Cxx)");
append( 0xDF65, "CB Display Offline Funds Indicator (same block as DF05)");
append( 0xDF65, "Serial heartbeat Required");
append( 0xDF66, "SVN Number");
append( 0xDF66, "CB Terminal Type (same block as 9F35)");
append( 0xDF66, "Display Unsupported Card");
append( 0xDF68, "Enable/Disable STOP command processing");
append( 0xDF69, "ConfigureProprietaryTags");
append( 0xDF6A, "Enable/Disable Comm Error Recovery");
append( 0xDF6C, "Cubic FTP Phase 2 Mode Options");
append( 0xDF6D, "Cubic Mode 3 Match AID");
append( 0xDF6E, "Cubic Fixed Fare Amounts");
append( 0xDF6F, "Cubic Timestamp Data");
append( 0xDF70, "Loyalty Program ID");
append( 0xDF70, "Generic Name String");
append( 0xDF71, "Value Added Tax 1");
append( 0xDF71, "Generic Numeric");
append( 0xDF72, "Value Added Tax 2");
append( 0xDF72, "Generic Specification String");
append( 0xDF73, "Merchant Category Code");
append( 0xDF73, "Generic Implementation String");
append( 0xDF74, "Discover Optional Features");
append( 0xDF75, "Communications Error Message Delay");
append( 0xDF76, "TVR from GenAC");
append( 0xDF77, "ViVOpay MSR Custom Data Output Tag");
append( 0xDF78, "MC Timing Performance Enable");
append( 0xDF79, "Card Disable Mask");
append( 0xDF7A, "Card Disable Interval");
append( 0xDF7B, "Serial Port (UART) Inter-character Timeout Period");
append( 0xDF7C, "Auto Switch Feature");
append( 0xDF7D, "Track Formatting Feature");
append( 0xDF7F, "Improved Collision Detection & Media Removal Feature");
append( 0xFF69, "ViVOpay Proprietary Tag List");
append( 0xFF70, "Serial Finite State Machine Version");
append( 0xFF71, "Transaction Finite State Machine Version");
append( 0xFF72, "System Information Suite");
append( 0xFF73, "Serial Protocol Version");
append( 0xFF74, "Serial Protocol Suite");
append( 0xFF75, "L1 Paypass Version");
append( 0xFF76, "L1 LCR Version");
append( 0xFF77, "L2 Card App Version");
append( 0xFF78, "L2 Card App Suite");
append( 0xFF79, "GMEDs Data");
append( 0xFF79, "User Experience Version");
append( 0xFF7A, "User Experience Suite");
append( 0xFF7B, "ViVOtech Proprietary Suite");
append( 0xFF7C, "VIUDS Scheme IDs Supported");
append( 0xFF7D, "VIUDS Scheme ID Selection Criteria");
append( 0xFFE0, "Registered Application Provider Identifier (RID)");
append( 0xFFE1, "Partial Selection Allowed");
append( 0xFFE2, "Application Flow");
append( 0xFFE3, "Selection Features - GR 1.2.10");
append( 0xFFE4, "Group Number / Fallback Group");
append( 0xFFE5, "Max AID Length");
append( 0xFFE6, "AID Disabled");
append( 0xFFE7, "Interface Support");
append( 0xFFE8, "Exclude from Processing");
append( 0xFFE9, "Kernel ID Transaction Type Group List");
append( 0xFFEA, "Default Kernel ID");
append( 0xFFF0, "Specific Features Switch");
append( 0xFFF1, "Terminal Contactless Transaction Limit");
append( 0xFFF2, "Terminal IFD");
append( 0xFFF3, "Application Capability");
append( 0xFFF4, "Visa Reader Risk Flags");
append( 0xFFF6, "Torn Transaction Log Clean Interval (minutes)");
append( 0xFFF7, "Burst Mode");
append( 0xFFF8, "UI Scheme");
append( 0xFFF9, "LCD Font Size");
append( 0xFFFA, "LCD Delay Time");
append( 0xFFFB, "Language Option for LCD");
append( 0xFFFC, "Force MagStripe");
append(0xDF891B, "Poll Mode");
append(0xDF891C, "Interac Retry Limit");
append(0xDFDE04, "MSR Encryption Option");
append(0xDFEE0C, "PPSE Terminate Flags");
append(0xDFEE12, "KID");
append(0xDFEE15, "Application Selection Indicator");
append(0xDFEE16, "DUKPT Key or MKSK Select for Online PIN Encrypted");
append(0xDFEE17, "ICC Terminal Entry Mode");
append(0xDFEE18, "MSR Terminal Entry Mode");
append(0xDFEE19, "Online DOL");
append(0xDFEE1A, "Output data element");
append(0xDFEE1B, "Authorization Request data elements");
append(0xDFEE1E, "Contact Terminal Configuration (see below)");
append(0xDFEE1F, "Issuer script device limit, Range: 0~255 (Default: 128)");
append(0xDFEE20, "ICC Power on detect waiting time. (Unit: Sec) (Default: 60S)");
append(0xDFEE21, "ICC L1 waiting time. (Unit: Sec)(Default: 10 S)");
append(0xDFEE22, "Driver (Menu, Get PIN, Get MSR) Timeout. (Unit: Sec) (see below)");
append(0xDFEE23, "MSR Track Data");
append(0xDFEE24, "Force Acceptance (Default: 00)");
append(0xDFEE25, "ICC Response Code");
append(0xDFEE26, "Encryption Status Information");
append(0xDFEE27, "MSR Control");
append(0xDFEF1A, "TLV available");
append(0xDFEF1A, "Encrypted Sensitive Tags");
append(0xDFEF1A, "Auto Authenticate");
append(0xDFEF20, "MAC option in reponse data");
append(0xDFEF21, "BIN");
append(0xDFEF22, "AID");
append(0xDFEF23, "HMAC");
append(0xDFEF24, "HMAC KSN");
append(0xDFEF25, "Output Data Format Select");
append(0xDFEF26, "MSR fallback");
append(0xDFEF27, "Online capability");
append(0xDFEF28, "Disable Encrypt ON");
append(0xDFEF2C, "Terminal AID List");
append(0xDFEF2E, "Terminal Transaction Log");
append(0xDFEF2F, "CUP configuration");
append(0xDFEF30, "White List");
append(0xDFEF31, "Black List");
append(0xDFEF32, "Auto-Switch");
append(0xDFEF34, "Antenna Detection Switch");
append(0xDFEF35, "Communications Watchdog Period");
append(0xDFEF36, "Media Control & Status Tracking");
append(0xDFEF37, "Interface Select");
append(0xDFEF38, "Timeout for Next Command");
append(0xDFEF39, "Network Indicate");
append(0xDFEF3A, "Reader Behavior Mode");
append(0xDFEF3B, "Autopoll Transaction Separation Interval");
append(0xDFEF40, "Ascii-code encryption Tag57 TLV");
append(0xDFEF41, "MAC Verification Data for SRED");
append(0xDFEF42, "MAC Verification KSN for SRED");
append(0xDFEF43, "Local TZ/DST information");
append(0xDFEF44, "Combination Options");
append(0xDFEF45, "Removal Timeout");
append(0xDFEF46, "ACT Pass Response DOL");
append(0xDFEF47, "CDA Hash Input");
append(0xDFEF48, "Indicate - retrieve transaction result again due to Output RAM is Not enough");
append(0xDFEF49, "Outcome Parameter Set");
append(0xDFEF4A, "User Interface Request Data");
append(0xDFEF4B, "MSR Equivalent Data Option");
append(0xDFEF4C, "MSR Equivalent Data Track Lengths");
append(0xDFEF4D, "MSR Equivalent Data");
append(0xDFEF4E, "ACT MSD Response DOL");
append(0xDFEF4F, "ACT Decline Response DOL");
append(0xDFEF50, "Terminal Interchange Profile (JCB)");
append(0xDFEF51, "Bypass EMV Completion Output");
append(0xDFEF52, "Re-FallBack times");
append(0xDFEF53, "Dynamic Reader Limits");
append(0xDFEF54, "SmartTap AID Index");
append(0xDFEF55, "Kernel Specific Features");
append(0xDFEF56, "Retry Limit");
append(0xDFEF57, "PPSE Terminate Flags");
append(0xDFEF59, "Terminal Data Setting - Default Amount");
append(0xDFEF5A, "Terminal Data Setting - Tags to Return");
append(0xDFEF5B, "Mask for Tag5A");
append(0xDFEF5C, "Mask for Tag56");
append(0xDFEF5D, "Mask for Tag57");
append(0xDFEF5E, "Mask for Tag9F6B");
append(0xDFEF5F, "Mask for TagFFEE13");
append(0xDFEF60, "Mask for TagFFEE14");
append(0xDFEF61, "Error Code");
append(0xDFEF62, "Allow MSR Swipe data from ICC Card");
append(0xDFEF63, "Tags To Read Yet");
append(0xDFEF64, "Referral Timeout");
append(0xDFEF6E, "USB-KB Output Data Postfix");
append(0xDFEF6F, "Inter-character Delay for USB-KB Interface");
append(0xDFEF70, "PISCES dual interface interference prevention mechanism fine-tune parameters");
append(0xDFEF71, "Waiting ICC insert time");
append(0xDFEF72, "Pre-poll card mechanism control in ACT cmd & config setting");
append(0xDFEF73, "Transaction Message Type");
append(0xDFEF74, "Reference amplitude value");
append(0xDFEF75, "Reference delta value");
append(0xDFEF76, "Transaction Interface Type to activate");
append(0xDFEF77, "Timeout for waiting next command");
append(0xDFEF78, "EMV contact L2 display messages option");
append(0xDFEF79, "PIN block format (when TDES)");
append(0xDFEF7A, "Enable Apple Pay Check");
append(0xDFEF7B, "Apple Pay Status");
append(0xDFEF7C, "Track Bit Encoding");
append(0xDFEF7D, "Re-power on times");
append(0xDFEF7E, "Fallback response code list");
append(0xFFEE01, "ViVOpay TLV Group Tag");
append(0xFFEE02, "ViVOpay Pre-PPSE Special Flow Group Tag");
append(0xFFEE03, "ViVOpay Post-PPSE Special Flow Group Tag");
append(0xFFEE04, "M/Chip3 Intermediate Message Data");
append(0xFFEE05, "M/Chip3 Intermediate Message Marker");
append(0xFFEE06, "ApplePay VAS Container");
append(0xFFEE07, "Encrypted Sensitive Tags");
append(0xFFEE08, "Masked Tags");
append(0xFFEE0A, "BIN Range");
append(0xFFEE0B, "AID Range");
append(0xFFEE0C, "White List");
append(0xFFEE10, "ViVOpay MChip Group Tag");
append(0xFFEE11, "ViVOpay Discover Group Tag");
append(0xFFEE12, "KID");
append(0xFFEE12, "Cash Reader Risk Record");
append(0xFFEE13, "Track 1 Data");
append(0xFFEE13, "Cashback Reader Risk Record");
append(0xFFEE14, "Track 2 Data");
append(0xFFEE14, "DRL Record 1");
append(0xFFEE15, "DRL Record 2");
append(0xFFEE16, "DRL Record 3");
append(0xFFEE17, "DRL Record 4");
append(0xFFEE18, "Tags To Write Yet Before GenAC");
append(0xFFEE19, "Tags To Write Yet After GenAC");
append(0xFFEE1A, "Terminal App DET Data");
append(0xFFEE1C, "Unpredictable Number Range");
append(0xFFEE1D, "Sensitive Data Mask");
append(0xFFEE1E, "Group 0 Initialize Flag ");
append(0xFFEE1F, "Error Code Table");
append(0xFFEE20, "Restart Deactivation Time");
}
};

static CData Data;
}

//--------------------------------------------------------------------------------

+ 1
- 0
3.0/src/includes/Hardware/Protocols/FR/AFPFR.h View File

@@ -0,0 +1 @@
#include "../../../../modules/Hardware/Protocols/FR/AFP/src/AFPFR.h"

+ 6
- 0
3.0/src/interface/modern/info_popup2.ini View File

@@ -0,0 +1,6 @@
[graphics_item]
type=qml
name=InfoPopup2

[qml]
item=info_popup2.qml

+ 91
- 0
3.0/src/interface/modern/info_popup2.qml View File

@@ -0,0 +1,91 @@
/* @file Всплывающее окно для отображения внешнего компонента */

import QtQuick 1.1
import Core.Types 1.0
import "widgets" 1.0 as Widgets
import "controls" 1.0 as Controls
import "scripts/gui.js" 1.0 as GUI
import "plugins" 1.0

Item {
id: rootItem

width: 1280
height: 1024

Column {
width: 1211
y: 197

anchors { horizontalCenter: parent.horizontalCenter }

Rectangle {
width: parent.width
height: 657
x: 1
color: "transparent"
border.color: Utils.ui.color("color.main.secondary")
border.width: 7
radius: 8

Loader {
id: container

anchors.centerIn: parent
}
}

Widgets.Spacer { height: 20 }

Widgets.Button {
anchors { horizontalCenter: parent.horizontalCenter }
icon: 18
text: Utils.locale.tr(QT_TR_NOOP("info_popup#close"))
color: Utils.ui.color("color.button.secondary")
texture: Utils.ui.image("button.secondary.normal")
texturePressed: Utils.ui.image("button.secondary.pressed")

width: 407
onClicked: { hideAnimation.start(); }
}
}

NumberAnimation {
id: showAnimation

target: rootItem
property: "opacity"
duration: 200
from: 0
to: 1
}

NumberAnimation {
id: hideAnimation

target: rootItem
property: "opacity"
duration: 200
from: 1
to: 0

onCompleted: hide()
}

function hide() {
Core.graphics.hidePopup();
Core.postEvent(Core.EventType.UpdateScenario, {signal: "popup_notify", result: container.item.result()});
}

QtObject {
id: global
}

function resetHandler(aParameters) {
container.sourceComponent = aParameters.obj
}

function showHandler() {
showAnimation.start();
}
}

+ 380
- 0
3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReader.cpp View File

@@ -0,0 +1,380 @@
/* @file Кардридер Creator. */

// Modules
#include "Hardware/CardReaders/CardReaderStatusesDescriptions.h"

// Project
#include "CreatorReader.h"
#include "../EMV/EMVAdapter.h"
#include "CreatorReaderConstants.h"
#include "CreatorReaderModelData.h"

using namespace SDK::Driver;

//------------------------------------------------------------------------------
CreatorReader::CreatorReader()
{
mDeviceName = CCreatorReader::DefaultName;
mPollingInterval = 300;
mCardPosition = CCreatorReader::CardPosition::Unknown;
mICCPUType = CCreatorReader::CardTypes::EICCPU::Unknown;
mMaxBadAnswers = 1;

mDetectingData = CUSBDevice::PDetectingData(new CCreatorReader::ModelData());

mStatusCodesSpecification = DeviceStatusCode::PSpecifications(new CardReaderStatusCode::CSpecifications());
}

//--------------------------------------------------------------------------------
QStringList CreatorReader::getModelList()
{
QStringList models;

foreach (CUSBDevice::CData modelData, CCreatorReader::ModelData().data())
{
foreach (CUSBDevice::SData data, modelData.data())
{
models << data.model;
}
}

return models;
}

//--------------------------------------------------------------------------------
bool CreatorReader::updateParameters()
{
if (!processCommand(CCreatorReader::Commands::UnLockInitialize) || !processCommand(CCreatorReader::Commands::SetMCReadingMode))
{
return false;
}

QByteArray data;

if (processCommand(CCreatorReader::Commands::GetSerialNumber, &data))
{
setDeviceParameter(CDeviceData::SerialNumber, data.mid(2));
}

return true;
}

//--------------------------------------------------------------------------------
TResult CreatorReader::processCommand(const QByteArray & aCommand, QByteArray * aAnswer, bool aIOLogsDebugMode)
{
QByteArray commandData;

return processCommand(aCommand, commandData, aAnswer, aIOLogsDebugMode);
}

//--------------------------------------------------------------------------------
TResult CreatorReader::processCommand(const QByteArray & aCommand, const QByteArray & aCommandData, QByteArray * aAnswer, bool aIOLogsDebugMode)
{
mProtocol.setPort(mIOPort);
mProtocol.setLog(mLog);

QByteArray answer;
QByteArray command = CCreatorReader::Markers::Command + aCommand + aCommandData;

if (aAnswer)
{
aAnswer->clear();
}

TResult result = mProtocol.processCommand(command, answer, aIOLogsDebugMode);

if (!result)
{
return result;
}

if (!checkAnswer(command, answer))
{
return CommandResult::Answer;
}

if (answer.startsWith(CCreatorReader::Markers::Error))
{
QByteArray errorBuffer = answer.mid(1, 2);
bool OK;
int error = errorBuffer.toInt(&OK);
QString log = QString("%1: Error: %2").arg(mDeviceName).arg(CCreatorReader::ErrorDescriptions[error]);

if (!OK)
{
log += QString(" (0x%1)").arg(errorBuffer.toHex().data());
}
else if (!CCreatorReader::ErrorDescriptions.data().contains(error))
{
log += QString(" (%1)").arg(error);
}

toLog(LogLevel::Error, log);

return CommandResult::Device;
}

if (aAnswer)
{
*aAnswer = answer.mid(3);
}

//TODO: возможно - обход ошибок

return CommandResult::OK;
}

//--------------------------------------------------------------------------------
bool CreatorReader::checkAnswer(const QByteArray & aCommand, const QByteArray & aAnswer)
{
// команда
QByteArray command = aAnswer.mid(1, 2);
QByteArray dataCommand = aCommand.mid(1, 2);

if (command != dataCommand)
{
toLog(LogLevel::Error, QString("%1: command = {%2}, need = {%3}").arg(mDeviceName).arg(command.toHex().data()).arg(dataCommand.toHex().data()));
return false;
}

// маркер
char answerMarker = aAnswer[0];

if ((answerMarker != CCreatorReader::Markers::Error) && (answerMarker != CCreatorReader::Markers::OK))
{
toLog(LogLevel::Error, QString("%1: wrong marker = %2, need = %3 or %4")
.arg(mDeviceName)
.arg(ProtocolUtils::toHexLog(answerMarker))
.arg(ProtocolUtils::toHexLog(CCreatorReader::Markers::Error))
.arg(ProtocolUtils::toHexLog(CCreatorReader::Markers::OK)));
return false;
}

return true;
}

//--------------------------------------------------------------------------------
bool CreatorReader::getStatus(TStatusCodes & aStatusCodes)
{
//TODO: реализовать протокол карты
QByteArray answer;

if (!CORRECT(processCommand(CCreatorReader::Commands::GetStatus, &answer)))
{
return false;
}

answer = answer.left(2);

bool OK1;
int ST1 = answer.left(1).toInt(&OK1);

bool OK0;
int ST0 = answer.right(1).toInt(&OK0);

if (!OK1 || !OK0 || (ST1 && (ST1 != CCreatorReader::CardPosition::ST1)) || (ST0 < CCreatorReader::CardPosition::Ejected) || (ST0 > CCreatorReader::CardPosition::Inserted))
{
aStatusCodes.insert(DeviceStatusCode::Error::Unknown);
}
else if (mCardPosition != ST0)
{
int oldCardPosition = mCardPosition;
mCardPosition = ST0;

if (mCardPosition == CCreatorReader::CardPosition::Inserted)
{
int typeRF = 0;

if (processCommand(CCreatorReader::Commands::IdentifyRF, &answer) && (answer.size() >= 4))
{
QByteArray buffer = answer.mid(2, 2);
typeRF = buffer.toInt();

if (typeRF)
{
toLog(LogLevel::Normal, QString("%1: Inserted %2 card type %3 = {%4}.")
.arg(mDeviceName).arg(CCreatorReader::CardTypes::Description[ECardType::RF]).arg(CCreatorReader::CardTypes::RFDescription[typeRF]).arg(buffer.data()));
}
}

int typeIC = 0;

if (processCommand(CCreatorReader::Commands::IdentifyIC, &answer) && (answer.size() >= 4))
{
QByteArray buffer = answer.mid(2, 2);
typeIC = buffer.toInt();

if (typeIC)
{
toLog(LogLevel::Normal, QString("%1: Inserted %2 card type %3 = {%4}.")
.arg(mDeviceName).arg(CCreatorReader::CardTypes::Description[ECardType::MSIC]).arg(CCreatorReader::CardTypes::ICDescription[typeIC]).arg(buffer.data()));
}
}

QVariantMap cardData;
bool typeMS = readMSData(cardData);

if (typeMS)
{
toLog(LogLevel::Normal, QString("%1: Inserted %2 card type.").arg(mDeviceName).arg(CCreatorReader::CardTypes::Description[ECardType::MS]));
}

if (typeIC && !cardData.contains(CHardware::CardReader::Track1) && !cardData.contains(CHardware::CardReader::Track2))
{
QByteArray track2;

if (EMVAdapter(this).getTrack2(track2))
{
cardData[CHardware::CardReader::Track2] = track2;
}
}

if ((!typeMS && !typeIC && !typeRF) || cardData.isEmpty())
{
emitStatusCode(CardReaderStatusCode::Warning::NeedReloading, ECardReaderStatus::NeedReloading);
}
else if (typeMS && typeIC && typeRF) emit inserted(ECardType::MSICRF, cardData);
else if (typeMS && typeIC) emit inserted(ECardType::MSIC, cardData);
else if (typeIC) emit inserted(ECardType::IC, cardData);
else if (typeMS) emit inserted(ECardType::MS, cardData);
else if (typeRF) emit inserted(ECardType::RF, cardData);
else
{
toLog(LogLevel::Warning, QString("%1: Unknown composite card type.").arg(mDeviceName));
}
}
else if ((mCardPosition == CCreatorReader::CardPosition::Ejected) && (oldCardPosition != CCreatorReader::CardPosition::Unknown))
{
emit ejected();
}
}

//TODO: анализ постоянных ошибок, конвертация девайс-кодов в статус-коды

return true;
}

//------------------------------------------------------------------------------
bool CreatorReader::readMSData(QVariantMap & aData)
{
QByteArray answer;

if (processCommand(CCreatorReader::Commands::ReadMSData, &answer, true) || (answer.size() < 13))
{
return false;
}

QList<QByteArray> listingData = answer.mid(2).split(CCreatorReader::DataSeparator);

if (listingData.size() != 3)
{
toLog(LogLevel::Error, QString("%1: Wrong number of blocks = %2, need = 3").arg(mDeviceName).arg(listingData.size()));
return false;
}

auto parseData = [&] (int i, const QString & aResultDataKey) -> bool
{
if (listingData[i - 1].isEmpty())
{
toLog(LogLevel::Error, QString("%1: Data block %2 is empty").arg(mDeviceName).arg(i));
return false;
}

if (listingData[i - 1][0] == CCreatorReader::Markers::Error)
{
QString log = QString("%1: Failed to read data of block = %2").arg(mDeviceName).arg(i);

if (listingData[i - 1].size() > 2)
{
bool OK;
int error = listingData[i - 1].mid(1, 2).toInt(&OK);

if (OK)
{
log += ", error = " + CCreatorReader::MSErrorDescription[error];
}
}

toLog(LogLevel::Error, log);

return false;
}

aData[aResultDataKey] = listingData[i - 1].mid(1);

return true;
};

using namespace CHardware::CardReader;

bool track1 = parseData(1, Track1);
bool track2 = parseData(2, Track2);
bool track3 = parseData(3, Track3);

return track1 || track2 || track3;
}

//------------------------------------------------------------------------------
bool CreatorReader::isDeviceReady() const
{
return true;
}

//------------------------------------------------------------------------------
void CreatorReader::eject()
{
//TODO: реализовать
}

//------------------------------------------------------------------------------
bool CreatorReader::communicate(const QByteArray & aSendMessage, QByteArray & aReceiveMessage)
{
QByteArray command;

if (mICCPUType == CCreatorReader::CardTypes::EICCPU::T0)
{
command = CCreatorReader::Commands::ADPUT0;
}
else if (mICCPUType == CCreatorReader::CardTypes::EICCPU::T1)
{
command = CCreatorReader::Commands::ADPUT1;
}
else
{
return false;
}

if (!processCommand(command, aSendMessage, &aReceiveMessage, true))
{
return false;
}

aReceiveMessage = aReceiveMessage.mid(2);

return true;
}

//------------------------------------------------------------------------------
bool CreatorReader::reset(QByteArray & aAnswer)
{
using namespace CHardware::CardReader;

if (processCommand(CCreatorReader::Commands::PowerReset, &aAnswer) && (aAnswer.size() > 2))
{
bool OK;
mICCPUType = CCreatorReader::CardTypes::EICCPU::Enum(aAnswer.mid(2, 1).toInt(&OK));

if (OK)
{
aAnswer = aAnswer.mid(3);
toLog(LogLevel::Normal, QString("%1: IC card, type %2 {%3} has been successfully reset.")
.arg(mDeviceName).arg(CCreatorReader::CardTypes::ICCPUDescription[mICCPUType]).arg(aAnswer.toHex().data()));

return true;
}
}

return false;
}

//------------------------------------------------------------------------------

+ 65
- 0
3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReader.h View File

@@ -0,0 +1,65 @@
/* @file Кардридер Creator. */
#pragma once

// Modules
#include "Hardware/Common/USBDeviceBase.h"
#include "Hardware/Common/PortPollingDeviceBase.h"
#include "Hardware/CardReaders/ProtoMifareReader.h"
#include "Hardware/CardReaders/Creator.h"

// Project
#include "CreatorReaderDataTypes.h"

//------------------------------------------------------------------------------
class CreatorReader: public USBDeviceBase<PortPollingDeviceBase<ProtoMifareReader>>
{
SET_SERIES("Creator")

public:
CreatorReader();

/// Возвращает список поддерживаемых устройств.
static QStringList getModelList();

#pragma region SDK::Driver::ICardReader
/// Проверка доступности устройства и карты.
virtual bool isDeviceReady() const;

/// Выбросить карту (для моторизированных ридеров) или отключить электрически (для немоторизованных).
virtual void eject();
#pragma endregion

#pragma region SDK::Driver::IMifareReader
/// Сброс карты по питанию.
virtual bool reset(QByteArray & aAnswer);

/// Произвести обмен данными с ридером или картой
virtual bool communicate(const QByteArray & aSendMessage, QByteArray & aReceiveMessage);
#pragma endregion

protected:
/// Получить статус.
virtual bool getStatus(TStatusCodes & aStatusCodes);

/// Инициализация устройства.
virtual bool updateParameters();

/// Выполнить команду.
TResult processCommand(const QByteArray & aCommand, QByteArray * aAnswer = nullptr, bool aIOLogsDebugMode = false);
TResult processCommand(const QByteArray & aCommand, const QByteArray & aCommandData, QByteArray * aAnswer = nullptr, bool aIOLogsDebugMode = false);

/// Проверить ответ.
bool checkAnswer(const QByteArray & aCommand, const QByteArray & aAnswer);

/// Прочитать данные магнитной полосы.
bool readMSData(QVariantMap & aData);

/// Протокол.
Creator mProtocol;

/// Положение карты по отношению к кардридеру.
int mCardPosition;

/// Тип IC карты.
CCreatorReader::CardTypes::EICCPU::Enum mICCPUType;
};

+ 202
- 0
3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderConstants.h View File

@@ -0,0 +1,202 @@
/* @file Константы кардридеров на протоколе Creator. */

#pragma once

// SDK
#include <SDK/Drivers/ICardReader.h>

// Modules
#include "Hardware/Common/Specifications.h"

// Project
#include "CreatorReaderDataTypes.h"

//--------------------------------------------------------------------------------
namespace CCreatorReader
{
/// Разделитель прочитанных данных карты
const char DataSeparator = '\x7E';

/// Маркеры.
namespace Markers
{
const char Command = 'C'; /// Команда.
const char OK = 'P'; /// Ошибок нет.
const char Error = 'N'; /// Ошибка.
}

//--------------------------------------------------------------------------------
/// Команды.
namespace Commands
{
const char LockInitialize[] = "\x30\x30"; /// Инициализация с блокировкой карты.
const char UnLockInitialize[] = "\x30\x31"; /// Инициализация с разблокировкой карты.
const char GetSerialNumber[] = "\xA2\x30"; /// Получение серийного нормера.
const char GetStatus[] = "\x31\x30"; /// Получение статуса.
const char IdentifyIC[] = "\x50\x30"; /// Автоидентификация IC-карты.
const char IdentifyRF[] = "\x50\x31"; /// Автоидентификация RF-карты.
const char SetMCReadingMode[] = "\x36\x30\x30\x31\x37\x30"; /// Установка режима стения карт с магнитной полосой, читать все треки в ASCII-формате.
const char ReadMSData[] = "\x36\x31\x30\x37"; /// Чтение данных с магнитной полосы, читать все треки в ASCII-формате.
const char PowerReset[] = "\x51\x30\x30"; /// Сброс аппаратный для EMV-карт (cold reset).
const char ADPUT0[] = "\x51\x33"; /// ADPU запрос для карты с протоколом CPU T = 0.
const char ADPUT1[] = "\x51\x34"; /// ADPU запрос для карты с протоколом CPU T = 1.
}

//--------------------------------------------------------------------------------
/// Положение карты по отношению к кардридеру.
namespace CardPosition
{
const int Unknown = -1;

const int Ejected = 0;
const int InProcess = 1;
const int Inserted = 2;

const char ST1 = 1; /// Постоянная составляющая статуса - ST1.
}

//--------------------------------------------------------------------------------
/// Типы карт.
namespace CardTypes
{
const int Unknown = 0; /// Неизвестен.

namespace CardType = SDK::Driver::ECardType;

/// Описатель для типов карт.
class CDescriptions : public CDescription<CardType::Enum>
{
public:
CDescriptions()
{
setDefault("Unknown");

append(CardType::MS, "Magnetic strip");
append(CardType::MSIC, "IC with magnetic strip");
append(CardType::MSICRF, "RF + IC with magnetic strip");
append(CardType::IC, "IC");
append(CardType::RF, "RF");
}
};

static CDescriptions Description;

//--------------------------------------------------------------------------------
/// Описатель для IC-карт по типу CPU.
class CICCPUDescriptions : public CDescription<EICCPU::Enum>
{
public:
CICCPUDescriptions()
{
setDefault(Unknown);

append(EICCPU::Unknown, "Unknown");
append(EICCPU::T0, "T=0 CPU");
append(EICCPU::T1, "T=1 CPU");
}
};

static CICCPUDescriptions ICCPUDescription;

//--------------------------------------------------------------------------------
/// Описатель для IC-карт.
class CICDescriptions : public CDescription<int>
{
public:
CICDescriptions()
{
setDefault(Unknown);

append(10, "T=0 CPU");
append(11, "T=1 CPU");
append(20, "SL4442");
append(21, "SL4428");
append(30, "AT24C01");
append(31, "AT24C02");
append(32, "AT24C04");
append(33, "AT24C08");
append(34, "AT24C16");
append(35, "AT24C32");
append(36, "AT24C64");
append(37, "AT24C128");
append(38, "AT24C256");
}
};

static CICDescriptions ICDescription;

//--------------------------------------------------------------------------------
/// Описатель для RF-карт.
class CRFDescriptions : public CDescription<int>
{
public:
CRFDescriptions()
{
setDefault(Unknown);

append(10, "Mifare one S50");
append(11, "Mifare one S70");
append(12, "Mifare one UL");
append(20, "Type A CPU");
append(30, "Type B CPU");
}
};

static CRFDescriptions RFDescription;
}

//--------------------------------------------------------------------------------
/// Ошибки.
class CErrorDescriptions : public CDescription<int>
{
public:
CErrorDescriptions()
{
setDefault("Unknown");

append(0, "CM (Command Character) Error");
append(1, "PM (Parameter Character) Error");
append(2, "Command can not be executed");
append(3, "Out of hardware support");
append(4, "Command data error");
append(11, "Card latch operation failure");
append(15, "EEPROM error");
append(20, "Read magnetic card error(Exclusive-or bit error)");
append(21, "Read magnetic card error");
append(30, "Power down");
append(41, "IC card module operation failure");
append(60, "Short circuit of IC card power supply");
append(61, "IC card initialization failure");
append(62, "Out of IC card support command");
append(63, "IC card does not response ");
append(64, "Other than 63");
append(65, "Non-initialized of IC card ");
append(66, "Card type out of reader support");
append(69, "Not support EMV mode");
}
};

static CErrorDescriptions ErrorDescriptions;

//--------------------------------------------------------------------------------
/// Ошибки чтения магнитной полосы карты.
class CMSErrorDescriptions : public CDescription<int>
{
public:
CMSErrorDescriptions()
{
setDefault("Unknown");

append(20, "Exclusive-or parity error");
append(23, "Only have start sentinel, end sentinel and LRC bit");
append(24, "Blank Magnetic track");
append(26, "No start sentinel");
append(27, "No end sentinel");
append(28, "LRC error");
}
};

static CMSErrorDescriptions MSErrorDescription;
}

//--------------------------------------------------------------------------------

+ 16
- 0
3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderDataTypes.h View File

@@ -0,0 +1,16 @@
/* @file Типы данных кардридеров на протоколе Creator. */

#pragma once

//--------------------------------------------------------------------------------
namespace CCreatorReader { namespace CardTypes { namespace EICCPU
{
enum Enum
{
Unknown = -1,
T0,
T1
};
}}}

//--------------------------------------------------------------------------------

+ 24
- 0
3.0/src/modules/Hardware/Cardreaders/src/Creator/CreatorReaderModelData.h View File

@@ -0,0 +1,24 @@
/* @file Данные моделей Creator. */

#pragma once

#include "Hardware/Common/USBDeviceModelData.h"

//--------------------------------------------------------------------------------
namespace CCreatorReader
{
/// Название кардридера Creator по умолчанию.
const char DefaultName[] = "Unknown Creator cardreader";

/// Данные моделей.
class ModelData : public CUSBDevice::CDetectingData
{
public:
ModelData()
{
add(0x23d8, 0x0285, "Creator CRT-288K", true);
}
};
}

//--------------------------------------------------------------------------------

+ 156
- 0
3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVAdapter.cpp View File

@@ -0,0 +1,156 @@
/* @file Класс-обёртка над EMV протоколом. */

#include "EMVAdapter.h"
#include "EMVConstants.h"

#include "TLV.h"

namespace EMV
{
Application AidList[] =
{
Application("A0000000031010", "VISA"),
Application("A0000000041010", "MC"),
Application("A0000004320001", "PRO100"),
Application("A0000000032010", "VISA Electron"),
Application("A0000000046000", "Cirrus"),
Application("A00000002501", "AMEX")
};
}

// Во многом логика взята отсюда: http://blog.saush.com/2006/09/08/getting-information-from-an-emv-chip-card/

//------------------------------------------------------------------------------
EMVAdapter::EMVAdapter() : mReader(nullptr)
{
}

//------------------------------------------------------------------------------
EMVAdapter::EMVAdapter(SDK::Driver::IMifareReader * aReader) : mReader(aReader)
{
}

//------------------------------------------------------------------------------
bool EMVAdapter::selectApplication(const EMV::Application & aApp, bool aFirst)
{
return selectApplication(QByteArray::fromHex(aApp.aid.toLatin1()), aFirst);
}

//------------------------------------------------------------------------------
bool EMVAdapter::selectApplication(const QByteArray & aAppID, bool aFirst)
{
QByteArray request = EMV::Command::SelectPSE;

if (!aFirst)
{
request[3] = 0x02;
}

request.append(char(aAppID.size()));
request.append(aAppID);
request.append(char(0));

QByteArray response;

return mReader->communicate(request, response) &&
(response.left(2) == QByteArray::fromRawData("\x90\x00", 2) || response.at(0) == EMV::Tags::FCI);
}

//------------------------------------------------------------------------------
bool EMVAdapter::getTrack2(QByteArray & aData)
{
QByteArray answer;

if (!mReader->reset(answer))
{
return false;
}

// Пытаемся выбрать платежное средство какие знаем
for (int i = 0; i < sizeof(EMV::AidList) / sizeof(EMV::AidList[0]); ++i)
{
if (selectApplication(EMV::AidList[i]))
{
mApp = EMV::AidList[i];

answer.clear();

if (getAFL(answer))
{
mApp.sfi = answer[0] >> 3;
mApp.recordIndex = answer[1];
}

answer.clear();

if (readRecord(mApp.recordIndex, answer))
{
EMV::TLV::SItem item = EMV::TLV::TLVs(answer).getTag(EMV::Tags::Track2);

if (!item.isEmpty())
{
aData = item.body.toHex().replace('D', '=').replace('d', '=');

return true;
}
}
// если нашли проложение но не смогли получить номер карты - значит дальше перебирать смысла нет
return false;
}
}

return false;
}

//------------------------------------------------------------------------------
bool EMVAdapter::readRecord(quint8 aRecIndex, QByteArray & aResponse)
{
QByteArray request = EMV::Command::ReadRecord;
request[2] = aRecIndex;
request[3] = (mApp.sfi << 3) | 0x04;

if (mReader->communicate(request, aResponse))
{
if (aResponse.at(0) == EMV::Tags::WrongLen)
{
request[4] = aResponse[1];
aResponse.clear();
return mReader->communicate(request, aResponse) && aResponse.at(0) == EMV::Tags::EMVTemplate;
}

return aResponse.at(0) == EMV::Tags::EMVTemplate;
}

return false;
}

//------------------------------------------------------------------------------
bool EMVAdapter::getAFL(QByteArray & aResponse)
{
QByteArray response;

if (mReader->communicate(EMV::Command::GetProcessingOptions, response) && !response.isEmpty())
{
// EMV Book 3: 6.5.8.4 Data Field Returned in the Response Message
if (response.at(0) == char(EMV::Tags::ResponseFormat1))
{
EMV::TLV::SItem item = EMV::TLV::TLVs(response).getTag(EMV::Tags::ResponseFormat1);
aResponse = item.body.mid(2);
return !aResponse.isEmpty();
}

EMV::TLV::SItem item = EMV::TLV::TLVs(response).getTag(EMV::Tags::AFL);

if (!item.isEmpty())
{
aResponse = item.body;
return !aResponse.isEmpty();
}
}

return false;
}

//------------------------------------------------------------------------------

+ 61
- 0
3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVAdapter.h View File

@@ -0,0 +1,61 @@
/* @file Класс-обёртка над EMV протоколом. */
#pragma once

// Qt
#include <Common/QtHeadersBegin.h>
#include <QtCore/QByteArray>
#include <Common/QtHeadersEnd.h>

// SDK
#include <SDK/Drivers/IMifareReader.h>

namespace EMV
{
// http://en.wikipedia.org/wiki/EMV#Application_selection
struct Application
{
QString aid;
QString name;
quint8 sfi; // short file identifier
quint8 recordIndex;

Application() : sfi(1), recordIndex(0) {}
Application(const QString & aAid, const QString & aName) : aid(aAid), name(aName), sfi(1), recordIndex(0) {}
};
}

//------------------------------------------------------------------------------
class EMVAdapter
{
public:
EMVAdapter();
EMVAdapter(SDK::Driver::IMifareReader * aReader);

/// Получить track 2 из EMV карты.
bool getTrack2(QByteArray & aData);

protected:
/// Выбрать платёжное приложение
bool selectApplication(const QByteArray & aAppID, bool aFirst = true);

/// Выбрать платёжное приложение
bool selectApplication(const EMV::Application & aApp, bool aFirst = true);

/// Прочитать дорожку карты
bool readRecord(quint8 aRecIndex, QByteArray & aResponse);

/// Getting Application File Locator (AFL)
bool getAFL(QByteArray & aResponse);

protected:
/// Экземпляр класса кардридера.
SDK::Driver::IMifareReader * mReader;

/// Track 2 карты.
QString mTrack2;

/// Найденный EMV Application ID
EMV::Application mApp;
};

//------------------------------------------------------------------------------

+ 45
- 0
3.0/src/modules/Hardware/Cardreaders/src/EMV/EMVConstants.h View File

@@ -0,0 +1,45 @@
/* @file Константы логики работы с EMV-картами. */

#pragma once

// SDK
#include <SDK/Drivers/ICardReader.h>

// Modules
#include "Hardware/Common/Specifications.h"

//--------------------------------------------------------------------------------
namespace EMV
{
const QString PSE = "1PAY.SYS.DDF01";

// нужный тип карты http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt
const QByteArray VisaMastercardCartType = QByteArray::fromRawData("\x3B\x68\x00\x00", 4);

namespace Command
{
// ISO7816 select command (00 A4 04 00 size)
const QByteArray SelectPSE = QByteArray::fromRawData("\x00\xa4\x04\x00", 4);

// Прочитать дорожку 00 B2 01 0C nn
const QByteArray ReadRecord = QByteArray::fromRawData("\x00\xb2\x01\x0c\x00", 5);

// GET PROCESSING OPTIONS command
const QByteArray GetProcessingOptions = QByteArray::fromRawData("\x80\xA8\x00\x00\x02\x83\x00", 7);
}

// EMV4.3 Book 3 Annex A
namespace Tags
{
const quint16 Track2 = 0x0057; // Track 2 Equivalent Data
const quint16 AFL = 0x0094; // Application File Locator (AFL)

const quint16 EMVTemplate = 0x0070; // EMV Proprietary Template
const quint16 WrongLen = 0x006c;
const quint16 FCI = 0x006f; // File Control Information (FCI) Template
const quint16 ResponseFormat1 = 0x0080; // Response Message Template Format 1
const quint16 ResponseFormat2 = 0x0077; // Response Message Template Format 2
}
}

//--------------------------------------------------------------------------------

+ 143
- 0
3.0/src/modules/Hardware/Cardreaders/src/EMV/TLV.cpp View File

@@ -0,0 +1,143 @@
/* @file Функционал Tag-Len-Value.

Based on code from https://github.com/lumag/emv-tools/ (c) lumag
*/

// Project
#include "TLV.h"

//------------------------------------------------------------------------------
bool EMV::TLV::TLVs::parse(const QByteArray & aBuffer)
{
QByteArray copy = aBuffer;

return !parseItem(copy).isEmpty();
}

//------------------------------------------------------------------------------
quint16 EMV::TLV::TLVs::takeByte(QByteArray & aBuffer)
{
quint16 result = 0;

if (aBuffer.size() > 0 )
{
result = *((quint8 *)aBuffer.data());
aBuffer.remove(0, 1);
}

return result;
}

//------------------------------------------------------------------------------
EMV::TLV::SItem EMV::TLV::TLVs::parseItem(QByteArray & aBuffer)
{
quint16 tag = parseTag(aBuffer);
quint16 len = parseLen(aBuffer);

if (len > aBuffer.size() || len == Len::Invalid || tag == Tag::Invalid)
{
return SItem();
}

SItem it;
it.tag = tag;
it.body = aBuffer.left(len);
aBuffer.remove(0, len);

mItems << it;

if (it.isComplex())
{
QByteArray copy = it.body;

while (copy.size() > 0)
{
SItem it2 = parseItem(copy);

if (it2.isEmpty())
{
break;
}
}
}

return it;
}

//------------------------------------------------------------------------------
EMV::TLV::SItem EMV::TLV::TLVs::getTag(quint16 aTag)
{
foreach (auto i, mItems)
{
if (i.tag == aTag)
{
return i;
}
}

return SItem();
}

//------------------------------------------------------------------------------
quint16 EMV::TLV::TLVs::parseLen(QByteArray & aBuffer)
{
if (aBuffer.isEmpty())
{
return Len::Invalid;
}

quint16 l = takeByte(aBuffer);

if (!(l & Len::Long))
{
return l;
}

quint16 ll = l &~ Len::Long;

if (aBuffer.size() < ll)
{
return Len::Invalid;
}

/* FIXME - WTF? */
if (ll != 1)
{
return Len::Invalid;
}

return takeByte(aBuffer);
}

//------------------------------------------------------------------------------
quint16 EMV::TLV::TLVs::parseTag(QByteArray & aBuffer)
{
if (aBuffer.isEmpty())
{
return Tag::Invalid;
}

quint16 tag = takeByte(aBuffer);

if ((tag & Tag::ValueMask) != Tag::ValueCont)
{
return tag;
}

if (aBuffer.isEmpty())
{
return Tag::Invalid;
}

tag |= takeByte(aBuffer) << 8;

return tag;
}

//------------------------------------------------------------------------------
EMV::TLV::TLVs::TLVs(const QByteArray & aBuffer)
{
parse(aBuffer);
}

//------------------------------------------------------------------------------

+ 75
- 0
3.0/src/modules/Hardware/Cardreaders/src/EMV/TLV.h View File

@@ -0,0 +1,75 @@
/* @file Функционал Tag-Len-Value.

Based on code from https://github.com/lumag/emv-tools/ (c) lumag
*/

#pragma once

// Qt
#include <Common/QtHeadersBegin.h>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <Common/QtHeadersEnd.h>

//--------------------------------------------------------------------------------
namespace EMV
{
namespace TLV
{
namespace Tag
{
const quint16 ClassMask = 0xc0;
const quint16 Complex = 0x20;
const quint16 ValueMask = 0x1f;
const quint16 ValueCont = 0x1f;
const quint16 Invalid = 0;
}

namespace Len
{
const quint16 Long = 0x80;
const quint16 Mask = 0x7f;
const quint16 Invalid = 0;
}

struct SItem
{
quint16 tag;
QByteArray body;

SItem(): tag(Tag::Invalid) {}
bool isEmpty() const { return tag == 0 || body.isEmpty(); }
bool isComplex() const { return tag & Tag::Complex; }
};

/// Tag-Len-Value parser
class TLVs
{
public:
TLVs() {}
TLVs(const QByteArray & aBuffer);

/// Распарсить EMV TVL буфер
bool parse(const QByteArray & aBuffer);

/// Получить тег из списка
SItem getTag(quint16 aTag);

protected:
/// Распарсить элемент EMV TVL буфера
SItem parseItem(QByteArray & aBuffer);

/// Парсинг тега данных
quint16 parseTag(QByteArray & aBuffer);

/// Парсинг длинны данных
quint16 parseLen(QByteArray & aBuffer);

/// Взять первый байт и вернуть его в виде quint16
quint16 takeByte(QByteArray & aBuffer);

QList<SItem> mItems;
};
}}

//--------------------------------------------------------------------------------

+ 124
- 0
3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechCallbacks.cpp View File

@@ -0,0 +1,124 @@
/* @file Колбеки для функционала dll кардридера IDTech. */

// Qt
#include <Common/QtHeadersBegin.h>
#include <QtCore/QDebug>
#include <Common/QtHeadersEnd.h>

// Project
#include "IDTechCallbacks.h"

//------------------------------------------------------------------------------
void logMessageHotplugOut(int, int)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the USB hot-plug callback function to monitor the info when plug in/out the reader. <br/>
* It should be registered using the registerHotplugCallBk,
* The first integer parameter is device type, and the second integer parameter is either 0: Device Plugged Out or 1: Device Plugged In
*/
}

//------------------------------------------------------------------------------
void logSendingMessageOut(unsigned char *, int)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the send command callback function to monitor the sending command into the reader. <br/>
* It should be registered using the registerLogCallBk,
*/
}

//------------------------------------------------------------------------------
void logReadingMessageOut(unsigned char *, int)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the EMV callback function to get the transaction message/data/result. <br/>
* It should be registered using the emv_registerCallBk,
*/
}

//------------------------------------------------------------------------------
void getEMVDataPOut(int, int, unsigned char *, int, IDTTransactionData *, EMV_Callback *, int)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the EMV callback function to get the transaction message/data/result. <br/>
* It should be registered using the emv_registerCallBk,
*/
}

//------------------------------------------------------------------------------
void getMSRCardDataOut(int, IDTMSRData)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the MSR callback function to get the MSR card data <br/>
* It should be registered using the msr_registerCallBk,
*/
}

//------------------------------------------------------------------------------
void getMSRCardDataPOut(int, IDTMSRData *)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the MSR callback function to get the pointer to the MSR card data <br/>
* It should be registered using the msr_registerCallBk,
*/
}

//------------------------------------------------------------------------------
void getCTLSCardDataOut(int aType, IDTMSRData aCardData1) //MSR: void ctls_registerCallBk(pMSR_callBack pCTLSf) - libIDT_KioskIII.h
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the CTLS callback function to get the CTLS card data <br/>
*/

IDTechReader().getMSRCardData(aType, &aCardData1);
}

//------------------------------------------------------------------------------
void getCTLSCardDataPOut(int aType, IDTMSRData * aCardData1) //MSR: void ctls_registerCallBkp(pMSR_callBackp pCTLSf) - libIDT_KioskIII.h
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the CTLS callback function to get the pointer to the CTLS card data <br/>
*/

IDTechReader().getMSRCardData(aType, aCardData1);
}

//------------------------------------------------------------------------------
void getPinpadDataPOut(int, IDTPINData *)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the PINPad callback function to get the input PIN Pad data <br/>
* It should be registered using the pin_registerCallBk,
*/
}

//------------------------------------------------------------------------------
void getUpdatingStatusOut(int, int, int, int, int)
{
qDebug() << __FUNCTION_NAME__;

/**
* Define the FW callback function to get the status of the firmware update <br/>
* It should be registered using the device_registerFWCallBk,
*/
}

//------------------------------------------------------------------------------

+ 25
- 0
3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechCallbacks.h View File

@@ -0,0 +1,25 @@
/* @file Колбеки для функционала dll кардридера IDTech. */

#include "IDTechReader.h"

#ifndef __FUNCTION_NAME__
#if defined(WIN32) || defined(_WIN32) // Windows
#define __FUNCTION_NAME__ __FUNCTION__
#else //*Nix
#define __FUNCTION_NAME__ __func__
#endif
#endif

//------------------------------------------------------------------------------
void logMessageHotplugOut(int, int);
void logSendingMessageOut(unsigned char *, int);
void logReadingMessageOut(unsigned char *, int);
void getEMVDataPOut(int, int, unsigned char *, int, IDTTransactionData *, EMV_Callback *, int);
void getMSRCardDataOut (int, IDTMSRData);
void getMSRCardDataPOut(int, IDTMSRData *);
void getCTLSCardDataOut (int, IDTMSRData); //MSR: void ctls_registerCallBk( pMSR_callBack pCTLSf) - libIDT_KioskIII.h
void getCTLSCardDataPOut(int, IDTMSRData *); //MSR: void ctls_registerCallBkp(pMSR_callBackp pCTLSf) - libIDT_KioskIII.h
void getPinpadDataPOut(int, IDTPINData *);
void getUpdatingStatusOut(int, int, int, int, int);

//------------------------------------------------------------------------------

+ 81
- 0
3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechModelData.h View File

@@ -0,0 +1,81 @@
/* @file Данные моделей кардридеров IDTech. */

#pragma once

// IDTech SDK
#pragma warning(push, 1)
#include "libIDT_Device.h"
#pragma warning(pop)

// Modules
#include "Hardware/Common/Specifications.h"

//--------------------------------------------------------------------------------
/// Константы, команды и коды состояний устройств на протоколе ATOL.
namespace CIDTech
{
namespace Models
{
/// Название кардридера IDTech по умолчанию.
const char Default[] = "ViVOpay cardreader";

//TODO: убрать
const char Kiosk_III_IV[] = "IDTech ViVOpay Kiosk III/IV";

namespace EModes
{
enum Enum
{
Unknown = 0,
COM,
USB,
HID,
BT,
Keydoard
};
}

struct SData
{
QString name;
EModes::Enum mode;
bool SRED;
};

class CData: public CDescription<IDT_DEVICE_TYPE>
{
public:
CData()
{
/*
AUGUSTA_HID,
AUGUSTA_KB, // keyboard mode
AUGUSTA_S_HID,
AUGUSTA_S_KB,
AUGUSTA_S_TTK_HID,
SPECTRUM_PRO,
MINISMART_II,
L100,
UNIPAY,
UNIPAY_I_V, // UniPay 1.5
VP3300_AJ, // with Audio Jack
KIOSK_III,
KIOSK_III_S,
VENDI,
VP3300_USB,
UNIPAY_I_V_TTK,
VP3300_BT, // Bluetooth
VP8800,
NEO2,
MINISMART_II_COM,
SPECTRUM_PRO_COM,
KIOSK_III_COM,
KIOSK_III_S_COM,
NEO2_COM
*/
}
};
}
}

//--------------------------------------------------------------------------------

+ 329
- 0
3.0/src/modules/Hardware/Cardreaders/src/IDTech/IDTechReader.cpp View File

@@ -0,0 +1,329 @@
/* @file Кардридер IDTech. */

// IDTech SDK
#pragma warning(push, 1)
#include "libusb.h"
#pragma warning(pop)

// Modules
#include "SysUtils/ISysUtils.h"
#include "Hardware/CardReaders/CardReaderStatusesDescriptions.h"

// Project
#include "IDTechReader.h"
#include "IDTechModelData.h"
#include "IDTechCallbacks.h"
#include "Hardware/CardReaders/EMVTagData.h"

using namespace SDK::Driver;

IDTechReader * IDTechReader::mInstance = nullptr;
int IDTechReader::mInstanceCounter = 0;

//------------------------------------------------------------------------------
IDTechReader::IDTechReader()
{
if (!mInstance)
{
mInstance = this;
}

mInstanceCounter++;

mDeviceName = CIDTech::Models::Default;
mPollingInterval = 300;
mLibrariesInitialized = false;

mStatusCodesSpecification = DeviceStatusCode::PSpecifications(new CardReaderStatusCode::CSpecifications());
}

//--------------------------------------------------------------------------------
IDTechReader::~IDTechReader()
{
mInstanceCounter--;

if (!mInstanceCounter)
{
mInstance = nullptr;
}
}

//--------------------------------------------------------------------------------
QStringList IDTechReader::getModelList()
{
QStringList models = QStringList() << CIDTech::Models::Default;

return models;
}

//--------------------------------------------------------------------------------
template <class T>
bool IDTechReader::checkLibrary(const char * aName, const char * aFunctionName, std::function<QString(T)> aFunction)
{
HMODULE handle = ::LoadLibraryA(aName);

if (!handle)
{
toLog(LogLevel::Error, QString("Failed to load %1, %2.").arg(aName).arg(ISysUtils::getLastErrorMessage()));
return false;
}

T dllFunction = (T)::GetProcAddress(handle, aFunctionName);

if (!dllFunction)
{
toLog(LogLevel::Error, QString("Failed to define %1 function, %2.").arg(aFunctionName).arg(ISysUtils::getLastErrorMessage()));
}
else
{
toLog(LogLevel::Normal, QString("%1 is successfully loaded, %2").arg(aName).arg(aFunction(dllFunction)));
}

if (!::FreeLibrary(handle))
{
toLog(LogLevel::Error, QString("Failed to unload %1, %2.").arg(aFunctionName).arg(ISysUtils::getLastErrorMessage()));
return false;
}

return dllFunction;
}

//--------------------------------------------------------------------------------
template <class T>
bool IDTechReader::registerCallback(HMODULE aHandle, const char * aFunctionName, T aFunction)
{
typedef void (*TRegisterCallback)(T);
TRegisterCallback dllFunction = (TRegisterCallback)::GetProcAddress(aHandle, aFunctionName);