Guest User

Untitled

a guest
Oct 16th, 2019
688
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Wire.h>
  2. #include <SPI.h>
  3. #include <Adafruit_PN532.h>
  4. #include "ASOLED.h"
  5. #define PN532_SCK  (13)
  6. #define PN532_MOSI (11)
  7. #define PN532_SS   (10)
  8. #define PN532_MISO (12)
  9. Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
  10. ///////////GLOBAL_VAR/////////
  11. //////////////////////////////
  12.  uint8_t Ver;
  13.  uint8_t tmp;
  14.  uint8_t *reallocCheck;
  15.  uint8_t cardtype;
  16.  bool success;
  17.  char NameOnCard[21]={0x00,};
  18.  uint8_t CardNumber[10]={0x00,};
  19.  uint8_t ExpDate[2]={0x00,};
  20.  char AppLabel[21]={0x00,};
  21. ///////////////////////////////
  22. void setup(void)
  23.  {
  24.   Serial.begin(230400);
  25.   nfc.begin();
  26.   uint32_t versiondata = nfc.getFirmwareVersion();
  27.   if (! versiondata)
  28.   {
  29.     LD.printString_6x8("Didn't find PN53x board",0,0);
  30.     while (1);
  31.   }
  32.   LD.init();
  33.   LD.clearDisplay();
  34.   nfc.SAMConfig();
  35.   tmp=versiondata>>24&0xFF;
  36.   Ver=(tmp>>4)*10+(tmp&0x0F);
  37.   LD.printString_6x8("CONNECTED:     pn5", 0, 0);LD.printNumber((long)Ver, 108, 0);
  38.   LD.printString_6x8("Firmware ver:", 0, 1);LD.printNumber((long)(versiondata>>16) & 0xFF, 90, 1);
  39.   LD.printString_6x8(".", 96, 1);LD.printNumber((long)(versiondata>>8) & 0xFF, 100, 1);
  40.   LD.printString_12x16("Waiting...", 0, 4);
  41. }
  42. uint8_t GetResponse (uint8_t*apdu, size_t apduSize, uint8_t*responseR, bool &success)
  43. {
  44.   uint8_t response[255];
  45.   uint8_t responseLength = sizeof(response);
  46.   success = nfc.inDataExchange(apdu, apduSize, response, &responseLength);
  47.   if(success)
  48.   {
  49.     if(reallocCheck = (uint8_t *)realloc(responseR, responseLength*sizeof(uint8_t))){responseR=reallocCheck;}
  50.     memcpy(responseR,response,responseLength);
  51.   }
  52. return responseLength;
  53. }
  54. uint8_t Get_AID_Apdu(uint8_t*responseR, uint8_t responseRLength, uint8_t*apdu, uint8_t &type)
  55. {
  56.   int Q;
  57.   enum data
  58.   {
  59.     VISA = 0x0310,
  60.     MASTERCARD = 0x0410,
  61.     MIR = 0x0658
  62.   };
  63.   for(uint8_t i=0; i<responseRLength; i++)
  64.   {
  65.     if(responseR[i] == 0xA0 && responseR[i-1] == 0x07)
  66.     {
  67.       for(uint8_t j=5,n=0; n<7; j++,n++,i++)
  68.       {
  69.         Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
  70.         if(Q == VISA){type =4;}
  71.         if(Q == MASTERCARD){type =5;}
  72.         if(Q == MIR){type =2;}
  73.         apdu[j] = responseR[i];
  74.        }
  75.     }
  76.   }
  77.  return type;
  78. }
  79. void GetApplicationLabel(uint8_t*responseR, uint8_t responseRLength)
  80. {
  81.     for(int i=0;i<sizeof(AppLabel);i++)
  82.   {
  83.      AppLabel[i]=0x00;
  84.   }
  85.   uint8_t alSize;
  86.   uint8_t count=0;
  87.   for(uint8_t i=0; i<responseRLength; i++)
  88.   {
  89.     if(responseR[i] == 0x50)
  90.     {
  91.      count=responseR[i+1];
  92.      i+=2;
  93.      for(uint8_t j=0; j<count;j++,i++)
  94.      {
  95.       AppLabel[j]=responseR[i];
  96.      }
  97.      break;
  98.     }
  99.   }
  100. }
  101. uint8_t Get_PDOL(uint8_t*responseR,uint8_t responseRLength,bool &success)
  102. {
  103.   int Q;
  104.   uint8_t pdolSize=0;
  105.   for(uint8_t i=0; i<responseRLength-1; i++)
  106.   {
  107.     Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
  108.     if(Q == 0x9F38)
  109.     {
  110.       i+=2;
  111.       success=true;
  112.       pdolSize = responseR[i++];
  113.       uint8_t * pdol = (uint8_t *)malloc(pdolSize*sizeof(uint8_t));
  114.       for(int j =0;j<pdolSize; j++,i++)
  115.       {
  116.         pdol[j]=responseR[i];
  117.       }
  118.       if(reallocCheck = (uint8_t *)realloc(responseR, pdolSize*sizeof(uint8_t))){responseR = reallocCheck;}
  119.       memcpy(responseR,pdol,pdolSize);
  120.       free(pdol);
  121.       return pdolSize;
  122.     }
  123.   }
  124. }
  125. uint8_t PDOL_Generator(uint8_t*&responseR,uint8_t responseRLength)
  126. {
  127.   int Q;
  128.   uint8_t pdolSize=0;
  129.   uint8_t apduCount=7;
  130.   uint8_t count =0;
  131.   uint8_t * pdolDecode = (uint8_t *)malloc(1*sizeof(uint8_t));
  132.   enum data
  133.   {
  134.     AmountAuthorized = 0x9F02,
  135.     AmountOther = 0x9F03,
  136.     TerminalCountryCode = 0x9F1A,
  137.     TransactinCurrencyCode = 0x5F2A,
  138.     TerminalType = 0x9F35,
  139.     UnpredictableNumber = 0x9F37,
  140.     TerminalTransactionQualifiers = 0x9F66,
  141.     VLPTerminalSupportIndicator =  0x9F7A,
  142.     AdditionalTerminalCapabilities = 0x9F40,
  143.     ///////////////////////////////////////
  144.     TVR_TerminalVerificationResults = 0x9505,//тут 05 это размер тэг двузначный
  145.     TransactionDate = 0x9A03,//тут 03 это размер тэг двузначный
  146.     TransactionType = 0x9C01,//тут 01 это размер тэг двузначный
  147.     DataAuthenticationCode = 0x9F45,
  148.     ICC_DynamicNumber = 0x9F4C,
  149.     CardholderVerificationResultsCVM = 0x9F34,
  150.     TransactionTime = 0x9F21,
  151.     MerchantCustomData = 0x9F7C
  152.   };
  153.      uint8_t TVR_TerminalVerificationResultsV[] = {0x00, 0x00, 0x00, 0x00, 0x00}; //5 bytesTVR представляет собой серию бит, установленных терминалом, считывающим EMV-карту, на основе логических тестов (например, срок действия карты истек). Этот объект данных используется в решении терминала, принимать, отклонять или идти в режиме онлайн для транзакции платежа
  154.      uint8_t TransactionDateV[] =  {0x18, 0x02, 0x01}; //3 bytes Местная дата авторизации транзакции Терминал YYMMDD
  155.      uint8_t TransactionTypeV[] = {0x00}; // 1 bytes Указывает тип финансовой транзакции, представленной двумя первыми цифрами ISO 8583: 1987 Код обработки
  156.      uint8_t DataAuthenticationCodeV[] = {0x00,0x00}; //2 bytes Значение, присвоенное эмитентом, которое сохраняется терминалом во время процесса проверки данных подписанных статических приложений
  157.      uint8_t ICC_DynamicNumberV[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};// 8 byte s номер ICC  Временной вариант, сгенерированный ICC, который должен быть захвачен терминалом
  158.      uint8_t CardholderVerificationResultsCVMV[] = {0x1F, 0x03, 0x00};// 3 bytes Показывает результаты последнего CVM
  159.      uint8_t TransactionTimeV[] = {0x00, 0x00, 0x00};// 3 bytes Местное время, когда транзакция была авторизована
  160.      uint8_t MerchantCustomDataV[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//20 bytes   Any value different from zero
  161.      uint8_t AmountAuthorizedV[]= {0x00, 0x00, 0x00, 0x01, 0x00, 0x00};// - 06 сумма транзакции. Если не знаете - подставьте фиктивное значение, например 1000 руб. будет в виде: 00 00 00 10 00 00
  162.      uint8_t AmountOtherV[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//- 06 Always '00 00 00 00 00 00'
  163.      uint8_t TerminalCountryCodeV[] = {0x06,0x43};// - 02  Указывает страну терминала, представленную в соответствии с ISO 3166
  164.      uint8_t TransactinCurrencyCodeV[] = {0x06,0x43};// 02 код валюты транзакции. Для рублей будет в виде: 06 43
  165.      uint8_t TerminalTypeV[] = {0x22};// -1 ‘21’ – Online Only, Attended Merchant (POS) ‘24’ – Online Only, Unattended Merchant (POS) ‘14’ – Online Only, Unattended Financial Institution (ATM)
  166.      uint8_t UnpredictableNumberV[] = {0xDE, 0xAD, 0xBE, 0xFA};// 04 Значение, обеспечивающее изменчивость и уникальность генерации криптограммы
  167.      uint8_t TerminalTransactionQualifiersV[] = {0x34, 0xA0, 0x40, 0x00};// - 04 квалификаторы транзакции для терминала. могут быть E6 40 00 00, C6 40 00 00 ,A6 40 00 00 ,86 40 00 00 ,46 40 00 00 ,26 40 00 00
  168.      uint8_t VLPTerminalSupportIndicatorV[] =  {0x00};// - 01 '00' = Online only solution supported '01' = Offline/online solution supported
  169.      uint8_t AdditionalTerminalCapabilitiesV[] =  {0xFF, 0x00, 0xF0, 0xB0, 0x01};//Byte 1, Bits 8,7,6,5 (Transaction Type Goods, Cash, Services, Cashback) NOT ALLOWED TO CHANGE
  170.                                                                                  //Byte 4, Bits 2,1 (Code tables 10-9, these all need to be 0) NOT ALLOWED TO CHANGE
  171.                                                                                  //Byte 5, Bits 8,7,6,5,4,3,2,1 (Code tables 2-8, these all need to be 0, Bit 1 needs to be 1) NOT ALLOWED TO CHANGE
  172.                                                      
  173.   for(uint8_t i=0; i<responseRLength-1; i++)
  174.   {
  175.     Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
  176.     if(Q == AmountAuthorized)
  177.     {
  178.       //Serial.println("AmountAuthorized");
  179.       i+=2;
  180.       pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  181.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  182.       for(uint8_t j =0;j<6; j++,count++){pdolDecode[count]=AmountAuthorizedV[j];}
  183.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  184.     }
  185.    
  186.     if(Q == AmountOther)
  187.     {
  188.       //Serial.println("AmountOther");
  189.       i+=2;
  190.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  191.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  192.       for(uint8_t j =0;j<6; j++,count++){pdolDecode[count]=AmountOtherV[j];}
  193.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  194.     }
  195.    
  196.     if(Q == TerminalCountryCode)
  197.     {
  198.       //Serial.println("TerminalCountryCode");
  199.       i+=2;
  200.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  201.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  202.       for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=TerminalCountryCodeV[j];}
  203.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  204.     }
  205.    
  206.     if(Q == TerminalType)
  207.     {
  208.       //Serial.println("TerminalType");
  209.       i+=2;
  210.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  211.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  212.       for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=TerminalTypeV[j];}
  213.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  214.     }
  215.    
  216.     if(Q == TransactinCurrencyCode)
  217.     {
  218.       //Serial.println("TransactinCurrencyCode");
  219.       i+=2;
  220.       pdolSize =pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  221.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  222.       for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=TransactinCurrencyCodeV[j];}
  223.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  224.     }
  225.    
  226.     if(Q == UnpredictableNumber)
  227.     {
  228.       //Serial.println("UnpredictableNumber");
  229.       i+=2;
  230.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  231.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  232.       for(uint8_t j =0;j<4; j++,count++){pdolDecode[count]=UnpredictableNumberV[j];}
  233.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  234.     }
  235.    
  236.     if(Q == TerminalTransactionQualifiers)
  237.     {
  238.       //Serial.println("TerminalTransactionQualifiers");
  239.       i+=2;
  240.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  241.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  242.       for(uint8_t j =0;j<4; j++,count++){pdolDecode[count]=TerminalTransactionQualifiersV[j];}
  243.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  244.     }
  245.    
  246.     if(Q == VLPTerminalSupportIndicator)
  247.     {
  248.       //Serial.println("VLPTerminalSupportIndicator");
  249.       i+=2;
  250.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  251.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  252.       for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=VLPTerminalSupportIndicatorV[j];}
  253.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  254.     }
  255.    
  256.     if(Q == AdditionalTerminalCapabilities)
  257.     {
  258.       //Serial.println("AdditionalTerminalCapabilities");
  259.       i+=2;
  260.       pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  261.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  262.       for(uint8_t j =0;j<5; j++,count++){pdolDecode[count]=AdditionalTerminalCapabilitiesV[j];}
  263.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  264.     }
  265.     /////////////////////////////////////////////////////////////////////
  266.     if(Q == TVR_TerminalVerificationResults)//pppp
  267.     {
  268.       //Serial.println("TVR_TerminalVerificationResults");
  269.       i+=1;
  270.       pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  271.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  272.       for(uint8_t j =0;j<5; j++,count++){pdolDecode[count]=TVR_TerminalVerificationResultsV[j];}
  273.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  274.     }
  275.     if(Q == TransactionDate)//ppppp
  276.     {
  277.       //Serial.println("TransactionDate");
  278.       i+=1;
  279.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  280.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  281.       for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=TransactionDateV[j];}
  282.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  283.     }
  284.     if(Q == TransactionType)//pppp
  285.     {
  286.       //Serial.println("TransactionType");
  287.       i+=1;
  288.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  289.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  290.       for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=TransactionTypeV[j];}
  291.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  292.     }
  293.     if(Q == DataAuthenticationCode)
  294.     {
  295.       //Serial.println("DataAuthenticationCode");
  296.       i+=2;
  297.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  298.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  299.       for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=DataAuthenticationCodeV[j];}
  300.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  301.     }
  302.     if(Q == ICC_DynamicNumber)
  303.     {
  304.       //Serial.println("ICC_DynamicNumber");
  305.       i+=2;
  306.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  307.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  308.       for(uint8_t j =0;j<8; j++,count++){pdolDecode[count]=ICC_DynamicNumberV[j];}
  309.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  310.     }
  311.     if(Q == CardholderVerificationResultsCVM)
  312.     {
  313.       //Serial.println("CardholderVerificationResultsCVM");
  314.       i+=2;
  315.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  316.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  317.       for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=CardholderVerificationResultsCVMV[j];}
  318.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  319.     }
  320.     if(Q == TransactionTime)
  321.     {
  322.       //Serial.println("TransactionTime");
  323.       i+=2;
  324.       pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  325.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  326.       for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=TransactionTimeV[j];}
  327.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  328.     }
  329.     if(Q == MerchantCustomData)
  330.     {
  331.       //Serial.println("MerchantCustomData");
  332.       i+=2;
  333.       pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
  334.       if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
  335.       for(uint8_t j =0;j<20; j++,count++){pdolDecode[count]=MerchantCustomDataV[j];}
  336.       //nfc.PrintHexChar(pdolDecode,pdolSize);
  337.     }
  338.    
  339.   }
  340.   if(reallocCheck = (uint8_t *)realloc(responseR, pdolSize*sizeof(uint8_t)))
  341.   {
  342.   responseR = reallocCheck;
  343.   memcpy(responseR,pdolDecode,pdolSize);
  344.   free(pdolDecode);
  345.   return pdolSize;
  346.   }
  347. }
  348. void Get_PDOL_Apdu(uint8_t*responseR, uint8_t responseRLength,uint8_t*apdu)
  349. {
  350.  uint8_t apducount=7;
  351.  for(uint8_t i=0; i<responseRLength; i++,apducount++)
  352.   {
  353.     apdu[apducount] = responseR[i];
  354.   }
  355. }
  356. uint8_t Get_AFL(uint8_t*responseR, uint8_t responseRLength,bool &success)
  357. {
  358.  uint8_t AFLsize=1;
  359.  uint8_t * AFL = (uint8_t *)malloc(AFLsize*sizeof(uint8_t));
  360.  for(uint8_t i=0; i<responseRLength; i++)
  361.   {
  362.     if(responseR[i] == 0x94&&responseR[i+1] == 0x04 || responseR[i] == 0x94&&responseR[i+1] == 0x08 || responseR[i] == 0x94&&responseR[i+1] == 0x0C||responseR[i] == 0x94&&responseR[i+1] == 0x10 ||responseR[i] == 0x94&&responseR[i+1] == 0x14)
  363.     {
  364.      AFLsize=responseR[i+1];
  365.      if(reallocCheck = (uint8_t *)realloc(AFL, AFLsize*sizeof(uint8_t)));
  366.      i+=2;
  367.      for(uint8_t j=0; j<AFLsize;j++,i++)
  368.      {
  369.       AFL[j]=responseR[i];
  370.      }
  371.      if(reallocCheck = (uint8_t *)realloc(responseR, AFLsize*sizeof(uint8_t))){responseR = reallocCheck;}
  372.      memcpy(responseR,AFL,AFLsize);
  373.      free(AFL);
  374.      success=true;
  375.      return AFLsize;
  376.     }
  377.    }
  378. success=false;
  379. return false;
  380. }
  381. uint8_t SFIGenerator(uint8_t*responseR, uint8_t &responseRLength)
  382. {
  383.   uint8_t APDUCount=0;
  384.   uint8_t SFICounter=0;
  385.   uint8_t AFLCounter=0;
  386.   uint8_t AFLStringSize = responseRLength/4;
  387.   uint8_t AFLColomnSize = 4;
  388.   uint8_t AFL[AFLStringSize][AFLColomnSize];
  389.   ///////////////////////////////////////ФОРМИРУЕМ МАССИВ AFL//////////////////////////////////////////////////////
  390.   for(uint8_t i = 0; i<AFLStringSize; i++)
  391.   {
  392.     for(uint8_t j = 0; j<AFLColomnSize;j++)
  393.     {
  394.       AFL[i][j] = responseR[AFLCounter++];
  395.     }
  396.   }
  397.   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  398.  
  399.   for(uint8_t i = 0; i<AFLStringSize; i++)
  400.   {
  401.    
  402.     SFICounter = SFICounter + ((AFL[i][2])-(AFL[i][1])+1);//количество apdu по этому SFI
  403.     uint8_t SFI = AFL[i][0] >> 3;
  404.     uint8_t P2 = SFI<<3|0b00000100; //НАШ SFI из P2
  405.     //Serial.print("P2 - ");Serial.println(P2 ,HEX);
  406.     if(reallocCheck = (uint8_t *)realloc(responseR, (SFICounter*5)*sizeof(uint8_t)))
  407.       {
  408.         responseR = reallocCheck;
  409.         responseRLength = SFICounter*5;
  410.       }
  411.       for(uint8_t j = APDUCount,GEN = AFL[i][1]; GEN<=AFL[i][2]; j+=5,APDUCount+=5,GEN++)
  412.       {
  413.         responseR[j]=0x00;
  414.         responseR[j+1]=0xB2;
  415.         responseR[j+2]=GEN;
  416.         responseR[j+3]=P2;
  417.         responseR[j+4]=0x00;
  418.       }
  419.   }
  420.   return APDUCount;
  421. }
  422. bool Get_PAN(uint8_t*responseR, uint8_t &responseRLength)
  423. {
  424.   memset(CardNumber, 0x00, sizeof(CardNumber));
  425.   byte tmpSize=responseRLength;
  426.   uint8_t count=0;
  427.   for(uint8_t i=0; i<responseRLength-1; i++)
  428.   {
  429.     if((responseR[i]==0x5A && responseR[i+1]==0x08)||(responseR[i]==0x5A && responseR[i+1]==0x0A))
  430.     {
  431.       responseRLength=responseR[i+1];
  432.       i+=2;
  433.       while(count<responseRLength)
  434.       {
  435.         CardNumber[count++]=responseR[i++];
  436.       }
  437.       responseRLength=tmpSize;
  438.       return true;
  439.     }
  440.   }
  441.   return false;
  442. }
  443. bool Get_EXP(uint8_t*responseR, uint8_t &responseRLength)
  444. {
  445.   memset(ExpDate, 0x00, sizeof(ExpDate));
  446.   uint8_t Q;
  447.   uint8_t count=0;
  448.   for(uint8_t i=0; i<responseRLength-1; i++)
  449.   {
  450.     if(responseR[i]==0x5F && responseR[i+1]==0x24)
  451.     {
  452.       i+=3;
  453.       ExpDate[1]=responseR[i];
  454.       ExpDate[0]=responseR[i+1];
  455.       return true;
  456.     }
  457.   }
  458.   return false;
  459. }
  460. bool Get_Pan_From_Track2(uint8_t*responseR, uint8_t &responseRLength,bool &success)
  461. {
  462.   memset(CardNumber, 0x00, sizeof(CardNumber));
  463.   byte tmpSize=responseRLength;
  464.   uint8_t count=0;
  465.   uint8_t Q;
  466.   for(uint8_t i=0; i<responseRLength-1; i++)
  467.   {
  468.     if(responseR[i]==0x57 && responseR[i+10])
  469.     {
  470.       responseRLength=8;
  471.       i+=2;
  472.       while(count<responseRLength)
  473.       {
  474.         CardNumber[count++]=responseR[i++];
  475.       }
  476.       responseRLength=tmpSize;
  477.       success=true;
  478.       return true;
  479.     }
  480.   }
  481.   success=false;
  482.   return false;
  483. }
  484. bool Get_EXP_From_Track2(uint8_t*responseR, uint8_t &responseRLength,bool &success)
  485. {
  486.   memset(ExpDate, 0x00, sizeof(ExpDate));
  487.   uint8_t Q;
  488.   for(uint8_t i=0; i<responseRLength-1; i++)
  489.   {
  490.     Q=responseR[i];
  491.     if((Q&0x10) && !(Q&0x20) && (Q&0x40) && (Q&0x80))
  492.     {
  493.       responseR[i]<<=4;
  494.       responseR[i]>>=4;
  495.       ExpDate[1]=responseR[i];
  496.       i++;
  497.       ExpDate[1] = (ExpDate[1] << 4)|(responseR[i]&0xF0)>>4;
  498.       ExpDate[0] = responseR[i]&0x0F;
  499.       i++;
  500.       ExpDate[0] = (ExpDate[0] << 4)|(responseR[i]&0xF0)>>4;
  501.       success=true;
  502.       return true;
  503.       }
  504.   }
  505.   success=false;
  506.   return false;
  507. }
  508. void Get_NAME(uint8_t*responseR, uint8_t &responseRLength)
  509. {
  510.   memset(NameOnCard, 0x00, sizeof(NameOnCard));
  511.   byte tmpSize=responseRLength;
  512.   uint8_t count=0;
  513.   for(uint8_t i=0; i<responseRLength-1; i++)
  514.   {
  515.     if(responseR[i]==0x5F && responseR[i+1]==0x20)
  516.     {
  517.       responseRLength=responseR[i+2];
  518.       i+=3;
  519.       while(count<responseRLength)
  520.       {
  521.         NameOnCard[count++]=responseR[i++];
  522.       }
  523.       responseRLength=tmpSize;
  524.       return;
  525.     }
  526.   }
  527. }
  528. void Read_AFL(uint8_t*responseR, uint8_t &responseRLength,bool &success)
  529. {
  530.   uint8_t AFLCounter =0;
  531.   uint8_t AFLStringSize = responseRLength/5;
  532.   uint8_t AFLColomnSize = 5;
  533.   uint8_t AFL[AFLStringSize][AFLColomnSize];
  534.   for(uint8_t i = 0; i<AFLStringSize; i++)
  535.   {
  536.     for(uint8_t j = 0; j<AFLColomnSize;j++)
  537.     {
  538.       AFL[i][j] = responseR[AFLCounter++];
  539.     }
  540.   }
  541.   for(uint8_t i = 0; i<AFLStringSize; i++)
  542.   {
  543.     responseRLength = GetResponse(AFL[i],5,responseR,success);
  544.     if(Get_PAN(responseR,responseRLength))
  545.     {
  546.       if(Get_EXP(responseR,responseRLength))
  547.       {
  548.         Get_NAME(responseR,responseRLength);
  549.       success=true;
  550.       return;
  551.       }
  552.      }
  553.   }
  554.   success=false;
  555. }
  556. bool CHECK_PDOL(uint8_t*responseR,uint8_t responseRLength,bool &success)
  557. {
  558.   int Q;
  559.   for(uint8_t i =0; i<responseRLength-1; i++)
  560.   {
  561.     Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
  562.     if(Q == 0x9F38)
  563.     {
  564.       success=true;
  565.       return true;
  566.     }
  567.   }
  568.   success=false;
  569.   return false;
  570. }
  571. bool CHECK_AFL(uint8_t*responseR,uint8_t responseRLength,bool &success)
  572. {
  573.   for(uint8_t i =0; i<responseRLength-1; i++)
  574.   {
  575.     if(responseR[i] == 0x94&&responseR[i+1] == 0x04 || responseR[i] == 0x94&&responseR[i+1] == 0x08 || responseR[i] == 0x94&&responseR[i+1] == 0x0C||responseR[i] == 0x94&&responseR[i+1] == 0x10 ||responseR[i] == 0x94&&responseR[i+1] == 0x14)
  576.     {
  577.       success=true;
  578.       return true;
  579.     }
  580.   }
  581.   success=false;
  582.   return false;
  583. }
  584. void array_to_string(uint8_t*arr, uint8_t arrsize, char*buf)
  585. {
  586.     for (byte i = 0; i < arrsize; i++)
  587.     {
  588.         byte nib1 = (arr[i] >> 4) & 0x0F;
  589.         byte nib2 = (arr[i] >> 0) & 0x0F;
  590.         buf[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
  591.         buf[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
  592.     }
  593.     buf[arrsize*2] = '\0';
  594. }
  595. void PrintAllData()
  596. {
  597.   byte Q;
  598.   byte count=0;
  599.   char big[20]={0x00,};
  600.   char small[16]={0x00,};
  601.   char ExpMM[2];
  602.   char ExpYY[2];
  603.   if(NameOnCard[0]!=0x00){LD.printString_6x8(NameOnCard, 0, 0);}
  604.   LD.printString_6x8(AppLabel, 0, 2);
  605.   if(cardtype==2){count=10;}else{count=8;}
  606.   LD.printString_6x8(AppLabel, 0, 2);
  607.   CardNumber[9] == 0x00 ? array_to_string(CardNumber,8,small),LD.printString_6x8(small, 0, 4) : array_to_string(CardNumber,10,big),LD.printString_6x8(big, 0, 4);
  608.   array_to_string(&ExpDate[0],1,ExpMM);
  609.   array_to_string(&ExpDate[1],1,ExpYY);
  610.   LD.printString_6x8(ExpMM, 0, 6);LD.printString_6x8("/", 12, 6);LD.printString_6x8(ExpYY, 18, 6);
  611.   }
  612. void loop()
  613. {
  614.   uint8_t * responseR = (uint8_t *)malloc(sizeof(uint8_t));
  615.   uint8_t responseRLength=0;
  616.   uint8_t apduSize=0;
  617.   success = nfc.inListPassiveTarget();
  618.   if(success)
  619.   {
  620.     LD.clearDisplay();
  621.     LD.printString_12x16("!!GetCard!!", 0, 2);
  622.     uint8_t apdu[] = {0x00, 0xA4, 0x04, 0x00, 0x0E, 0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00};
  623.     Serial.print("APDU: ");
  624.     nfc.PrintHexChar(apdu,sizeof(apdu));
  625.     responseRLength = GetResponse (apdu,sizeof(apdu),responseR,success);
  626.     Serial.print("Response: ");
  627.     nfc.PrintHexChar(responseR,responseRLength);
  628.     if(success)
  629.     {
  630.       uint8_t apdu[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  631.       Get_AID_Apdu(responseR,responseRLength,apdu,cardtype);
  632.       Serial.print("APDU: ");
  633.       nfc.PrintHexChar(apdu,sizeof(apdu));
  634.       responseRLength = GetResponse (apdu,sizeof(apdu),responseR,success);
  635.       Serial.print("Response: ");
  636.       nfc.PrintHexChar(responseR,responseRLength);
  637.       GetApplicationLabel(responseR,responseRLength);
  638.       if(success)
  639.       {
  640.         if(CHECK_PDOL(responseR,responseRLength,success))
  641.         {
  642.           responseRLength=Get_PDOL(responseR,responseRLength,success);
  643.           Serial.print("PDOL: ");
  644.           nfc.PrintHexChar(responseR,responseRLength);
  645.           responseRLength=PDOL_Generator(responseR,responseRLength);
  646.           Serial.print("PDOL_GENERATOR: ");
  647.           nfc.PrintHexChar(responseR,responseRLength);
  648.           apduSize=7+responseRLength+1;
  649.           uint8_t apdu[apduSize] = {0x80, 0xA8, 0x00, 0x00, 0x12, 0x83, responseRLength};
  650.           Get_PDOL_Apdu(responseR,responseRLength,apdu);
  651.           Serial.print("APDU: ");
  652.           nfc.PrintHexChar(apdu,sizeof(apdu));
  653.           responseRLength=GetResponse (apdu,apduSize,responseR,success);
  654.           if(responseRLength<5)
  655.           {
  656.             LD.printString_12x16("PDOL_ERROR", 0, 2);
  657.             return;
  658.           }
  659.           Serial.print("Response: ");
  660.           nfc.PrintHexChar(responseR,responseRLength);
  661.         }
  662.         else
  663.         {
  664.           uint8_t apdu[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00};
  665.           Serial.print("APDU: ");
  666.           nfc.PrintHexChar(apdu,sizeof(apdu));
  667.           responseRLength=GetResponse (apdu,sizeof(apdu),responseR,success);
  668.           Serial.print("Response: ");
  669.           nfc.PrintHexChar(responseR,responseRLength);
  670.         }
  671.         if(success)
  672.         {
  673.           if(CHECK_AFL(responseR,responseRLength,success))
  674.           {
  675.             responseRLength=Get_AFL(responseR,responseRLength,success);
  676.             responseRLength=SFIGenerator(responseR,responseRLength);
  677.             Serial.print("Response: ");
  678.             nfc.PrintHexChar(responseR,responseRLength);
  679.             Read_AFL(responseR,responseRLength,success);
  680.           }
  681.           else
  682.           {
  683.             if(Get_Pan_From_Track2(responseR, responseRLength,success))
  684.             {
  685.               if(Get_EXP_From_Track2(responseR, responseRLength,success))
  686.               {
  687.                 Get_NAME(responseR,responseRLength);
  688.               }
  689.             }
  690.           }
  691.         }
  692.       }
  693.     }
  694.     LD.clearDisplay();
  695.     PrintAllData();
  696.     if(success)
  697.     {
  698.       free(responseR);
  699.       reallocCheck=NULL;
  700.       cardtype=0;
  701.       success=false;
  702.       responseRLength=0;
  703.       apduSize=0;
  704.     }
  705.   }
  706. }
RAW Paste Data