Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Wire.h>
- #include <SPI.h>
- #include <Adafruit_PN532.h>
- #include "ASOLED.h"
- #define PN532_SCK (13)
- #define PN532_MOSI (11)
- #define PN532_SS (10)
- #define PN532_MISO (12)
- Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
- ///////////GLOBAL_VAR/////////
- //////////////////////////////
- uint8_t Ver;
- uint8_t tmp;
- uint8_t *reallocCheck;
- uint8_t cardtype;
- bool success;
- char NameOnCard[21]={0x00,};
- uint8_t CardNumber[10]={0x00,};
- uint8_t ExpDate[2]={0x00,};
- char AppLabel[21]={0x00,};
- ///////////////////////////////
- void setup(void)
- {
- Serial.begin(230400);
- nfc.begin();
- uint32_t versiondata = nfc.getFirmwareVersion();
- if (! versiondata)
- {
- LD.printString_6x8("Didn't find PN53x board",0,0);
- while (1);
- }
- LD.init();
- LD.clearDisplay();
- nfc.SAMConfig();
- tmp=versiondata>>24&0xFF;
- Ver=(tmp>>4)*10+(tmp&0x0F);
- LD.printString_6x8("CONNECTED: pn5", 0, 0);LD.printNumber((long)Ver, 108, 0);
- LD.printString_6x8("Firmware ver:", 0, 1);LD.printNumber((long)(versiondata>>16) & 0xFF, 90, 1);
- LD.printString_6x8(".", 96, 1);LD.printNumber((long)(versiondata>>8) & 0xFF, 100, 1);
- LD.printString_12x16("Waiting...", 0, 4);
- }
- uint8_t GetResponse (uint8_t*apdu, size_t apduSize, uint8_t*responseR, bool &success)
- {
- uint8_t response[255];
- uint8_t responseLength = sizeof(response);
- success = nfc.inDataExchange(apdu, apduSize, response, &responseLength);
- if(success)
- {
- if(reallocCheck = (uint8_t *)realloc(responseR, responseLength*sizeof(uint8_t))){responseR=reallocCheck;}
- memcpy(responseR,response,responseLength);
- }
- return responseLength;
- }
- uint8_t Get_AID_Apdu(uint8_t*responseR, uint8_t responseRLength, uint8_t*apdu, uint8_t &type)
- {
- int Q;
- enum data
- {
- VISA = 0x0310,
- MASTERCARD = 0x0410,
- MIR = 0x0658
- };
- for(uint8_t i=0; i<responseRLength; i++)
- {
- if(responseR[i] == 0xA0 && responseR[i-1] == 0x07)
- {
- for(uint8_t j=5,n=0; n<7; j++,n++,i++)
- {
- Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
- if(Q == VISA){type =4;}
- if(Q == MASTERCARD){type =5;}
- if(Q == MIR){type =2;}
- apdu[j] = responseR[i];
- }
- }
- }
- return type;
- }
- void GetApplicationLabel(uint8_t*responseR, uint8_t responseRLength)
- {
- for(int i=0;i<sizeof(AppLabel);i++)
- {
- AppLabel[i]=0x00;
- }
- uint8_t alSize;
- uint8_t count=0;
- for(uint8_t i=0; i<responseRLength; i++)
- {
- if(responseR[i] == 0x50)
- {
- count=responseR[i+1];
- i+=2;
- for(uint8_t j=0; j<count;j++,i++)
- {
- AppLabel[j]=responseR[i];
- }
- break;
- }
- }
- }
- uint8_t Get_PDOL(uint8_t*responseR,uint8_t responseRLength,bool &success)
- {
- int Q;
- uint8_t pdolSize=0;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
- if(Q == 0x9F38)
- {
- i+=2;
- success=true;
- pdolSize = responseR[i++];
- uint8_t * pdol = (uint8_t *)malloc(pdolSize*sizeof(uint8_t));
- for(int j =0;j<pdolSize; j++,i++)
- {
- pdol[j]=responseR[i];
- }
- if(reallocCheck = (uint8_t *)realloc(responseR, pdolSize*sizeof(uint8_t))){responseR = reallocCheck;}
- memcpy(responseR,pdol,pdolSize);
- free(pdol);
- return pdolSize;
- }
- }
- }
- uint8_t PDOL_Generator(uint8_t*&responseR,uint8_t responseRLength)
- {
- int Q;
- uint8_t pdolSize=0;
- uint8_t apduCount=7;
- uint8_t count =0;
- uint8_t * pdolDecode = (uint8_t *)malloc(1*sizeof(uint8_t));
- enum data
- {
- AmountAuthorized = 0x9F02,
- AmountOther = 0x9F03,
- TerminalCountryCode = 0x9F1A,
- TransactinCurrencyCode = 0x5F2A,
- TerminalType = 0x9F35,
- UnpredictableNumber = 0x9F37,
- TerminalTransactionQualifiers = 0x9F66,
- VLPTerminalSupportIndicator = 0x9F7A,
- AdditionalTerminalCapabilities = 0x9F40,
- ///////////////////////////////////////
- TVR_TerminalVerificationResults = 0x9505,//тут 05 это размер тэг двузначный
- TransactionDate = 0x9A03,//тут 03 это размер тэг двузначный
- TransactionType = 0x9C01,//тут 01 это размер тэг двузначный
- DataAuthenticationCode = 0x9F45,
- ICC_DynamicNumber = 0x9F4C,
- CardholderVerificationResultsCVM = 0x9F34,
- TransactionTime = 0x9F21,
- MerchantCustomData = 0x9F7C
- };
- uint8_t TVR_TerminalVerificationResultsV[] = {0x00, 0x00, 0x00, 0x00, 0x00}; //5 bytesTVR представляет собой серию бит, установленных терминалом, считывающим EMV-карту, на основе логических тестов (например, срок действия карты истек). Этот объект данных используется в решении терминала, принимать, отклонять или идти в режиме онлайн для транзакции платежа
- uint8_t TransactionDateV[] = {0x18, 0x02, 0x01}; //3 bytes Местная дата авторизации транзакции Терминал YYMMDD
- uint8_t TransactionTypeV[] = {0x00}; // 1 bytes Указывает тип финансовой транзакции, представленной двумя первыми цифрами ISO 8583: 1987 Код обработки
- uint8_t DataAuthenticationCodeV[] = {0x00,0x00}; //2 bytes Значение, присвоенное эмитентом, которое сохраняется терминалом во время процесса проверки данных подписанных статических приложений
- uint8_t ICC_DynamicNumberV[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};// 8 byte s номер ICC Временной вариант, сгенерированный ICC, который должен быть захвачен терминалом
- uint8_t CardholderVerificationResultsCVMV[] = {0x1F, 0x03, 0x00};// 3 bytes Показывает результаты последнего CVM
- uint8_t TransactionTimeV[] = {0x00, 0x00, 0x00};// 3 bytes Местное время, когда транзакция была авторизована
- 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
- uint8_t AmountAuthorizedV[]= {0x00, 0x00, 0x00, 0x01, 0x00, 0x00};// - 06 сумма транзакции. Если не знаете - подставьте фиктивное значение, например 1000 руб. будет в виде: 00 00 00 10 00 00
- uint8_t AmountOtherV[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};//- 06 Always '00 00 00 00 00 00'
- uint8_t TerminalCountryCodeV[] = {0x06,0x43};// - 02 Указывает страну терминала, представленную в соответствии с ISO 3166
- uint8_t TransactinCurrencyCodeV[] = {0x06,0x43};// 02 код валюты транзакции. Для рублей будет в виде: 06 43
- uint8_t TerminalTypeV[] = {0x22};// -1 ‘21’ – Online Only, Attended Merchant (POS) ‘24’ – Online Only, Unattended Merchant (POS) ‘14’ – Online Only, Unattended Financial Institution (ATM)
- uint8_t UnpredictableNumberV[] = {0xDE, 0xAD, 0xBE, 0xFA};// 04 Значение, обеспечивающее изменчивость и уникальность генерации криптограммы
- 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
- uint8_t VLPTerminalSupportIndicatorV[] = {0x00};// - 01 '00' = Online only solution supported '01' = Offline/online solution supported
- 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
- //Byte 4, Bits 2,1 (Code tables 10-9, these all need to be 0) NOT ALLOWED TO CHANGE
- //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
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
- if(Q == AmountAuthorized)
- {
- //Serial.println("AmountAuthorized");
- i+=2;
- pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<6; j++,count++){pdolDecode[count]=AmountAuthorizedV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == AmountOther)
- {
- //Serial.println("AmountOther");
- i+=2;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<6; j++,count++){pdolDecode[count]=AmountOtherV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TerminalCountryCode)
- {
- //Serial.println("TerminalCountryCode");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=TerminalCountryCodeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TerminalType)
- {
- //Serial.println("TerminalType");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=TerminalTypeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TransactinCurrencyCode)
- {
- //Serial.println("TransactinCurrencyCode");
- i+=2;
- pdolSize =pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=TransactinCurrencyCodeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == UnpredictableNumber)
- {
- //Serial.println("UnpredictableNumber");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<4; j++,count++){pdolDecode[count]=UnpredictableNumberV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TerminalTransactionQualifiers)
- {
- //Serial.println("TerminalTransactionQualifiers");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<4; j++,count++){pdolDecode[count]=TerminalTransactionQualifiersV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == VLPTerminalSupportIndicator)
- {
- //Serial.println("VLPTerminalSupportIndicator");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=VLPTerminalSupportIndicatorV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == AdditionalTerminalCapabilities)
- {
- //Serial.println("AdditionalTerminalCapabilities");
- i+=2;
- pdolSize =pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<5; j++,count++){pdolDecode[count]=AdditionalTerminalCapabilitiesV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- /////////////////////////////////////////////////////////////////////
- if(Q == TVR_TerminalVerificationResults)//pppp
- {
- //Serial.println("TVR_TerminalVerificationResults");
- i+=1;
- pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<5; j++,count++){pdolDecode[count]=TVR_TerminalVerificationResultsV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TransactionDate)//ppppp
- {
- //Serial.println("TransactionDate");
- i+=1;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=TransactionDateV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TransactionType)//pppp
- {
- //Serial.println("TransactionType");
- i+=1;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<1; j++,count++){pdolDecode[count]=TransactionTypeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == DataAuthenticationCode)
- {
- //Serial.println("DataAuthenticationCode");
- i+=2;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<2; j++,count++){pdolDecode[count]=DataAuthenticationCodeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == ICC_DynamicNumber)
- {
- //Serial.println("ICC_DynamicNumber");
- i+=2;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<8; j++,count++){pdolDecode[count]=ICC_DynamicNumberV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == CardholderVerificationResultsCVM)
- {
- //Serial.println("CardholderVerificationResultsCVM");
- i+=2;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=CardholderVerificationResultsCVMV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == TransactionTime)
- {
- //Serial.println("TransactionTime");
- i+=2;
- pdolSize = pdolSize+ responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<3; j++,count++){pdolDecode[count]=TransactionTimeV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- if(Q == MerchantCustomData)
- {
- //Serial.println("MerchantCustomData");
- i+=2;
- pdolSize = pdolSize+responseR[i];//Serial.print("Size ");Serial.println(responseR[i]); Serial.print("PDOLSize ");Serial.println(pdolSize);
- if(reallocCheck = (uint8_t *)realloc(pdolDecode, pdolSize*sizeof(uint8_t)));
- for(uint8_t j =0;j<20; j++,count++){pdolDecode[count]=MerchantCustomDataV[j];}
- //nfc.PrintHexChar(pdolDecode,pdolSize);
- }
- }
- if(reallocCheck = (uint8_t *)realloc(responseR, pdolSize*sizeof(uint8_t)))
- {
- responseR = reallocCheck;
- memcpy(responseR,pdolDecode,pdolSize);
- free(pdolDecode);
- return pdolSize;
- }
- }
- void Get_PDOL_Apdu(uint8_t*responseR, uint8_t responseRLength,uint8_t*apdu)
- {
- uint8_t apducount=7;
- for(uint8_t i=0; i<responseRLength; i++,apducount++)
- {
- apdu[apducount] = responseR[i];
- }
- }
- uint8_t Get_AFL(uint8_t*responseR, uint8_t responseRLength,bool &success)
- {
- uint8_t AFLsize=1;
- uint8_t * AFL = (uint8_t *)malloc(AFLsize*sizeof(uint8_t));
- for(uint8_t i=0; i<responseRLength; i++)
- {
- 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)
- {
- AFLsize=responseR[i+1];
- if(reallocCheck = (uint8_t *)realloc(AFL, AFLsize*sizeof(uint8_t)));
- i+=2;
- for(uint8_t j=0; j<AFLsize;j++,i++)
- {
- AFL[j]=responseR[i];
- }
- if(reallocCheck = (uint8_t *)realloc(responseR, AFLsize*sizeof(uint8_t))){responseR = reallocCheck;}
- memcpy(responseR,AFL,AFLsize);
- free(AFL);
- success=true;
- return AFLsize;
- }
- }
- success=false;
- return false;
- }
- uint8_t SFIGenerator(uint8_t*responseR, uint8_t &responseRLength)
- {
- uint8_t APDUCount=0;
- uint8_t SFICounter=0;
- uint8_t AFLCounter=0;
- uint8_t AFLStringSize = responseRLength/4;
- uint8_t AFLColomnSize = 4;
- uint8_t AFL[AFLStringSize][AFLColomnSize];
- ///////////////////////////////////////ФОРМИРУЕМ МАССИВ AFL//////////////////////////////////////////////////////
- for(uint8_t i = 0; i<AFLStringSize; i++)
- {
- for(uint8_t j = 0; j<AFLColomnSize;j++)
- {
- AFL[i][j] = responseR[AFLCounter++];
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- for(uint8_t i = 0; i<AFLStringSize; i++)
- {
- SFICounter = SFICounter + ((AFL[i][2])-(AFL[i][1])+1);//количество apdu по этому SFI
- uint8_t SFI = AFL[i][0] >> 3;
- uint8_t P2 = SFI<<3|0b00000100; //НАШ SFI из P2
- //Serial.print("P2 - ");Serial.println(P2 ,HEX);
- if(reallocCheck = (uint8_t *)realloc(responseR, (SFICounter*5)*sizeof(uint8_t)))
- {
- responseR = reallocCheck;
- responseRLength = SFICounter*5;
- }
- for(uint8_t j = APDUCount,GEN = AFL[i][1]; GEN<=AFL[i][2]; j+=5,APDUCount+=5,GEN++)
- {
- responseR[j]=0x00;
- responseR[j+1]=0xB2;
- responseR[j+2]=GEN;
- responseR[j+3]=P2;
- responseR[j+4]=0x00;
- }
- }
- return APDUCount;
- }
- bool Get_PAN(uint8_t*responseR, uint8_t &responseRLength)
- {
- memset(CardNumber, 0x00, sizeof(CardNumber));
- byte tmpSize=responseRLength;
- uint8_t count=0;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- if((responseR[i]==0x5A && responseR[i+1]==0x08)||(responseR[i]==0x5A && responseR[i+1]==0x0A))
- {
- responseRLength=responseR[i+1];
- i+=2;
- while(count<responseRLength)
- {
- CardNumber[count++]=responseR[i++];
- }
- responseRLength=tmpSize;
- return true;
- }
- }
- return false;
- }
- bool Get_EXP(uint8_t*responseR, uint8_t &responseRLength)
- {
- memset(ExpDate, 0x00, sizeof(ExpDate));
- uint8_t Q;
- uint8_t count=0;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- if(responseR[i]==0x5F && responseR[i+1]==0x24)
- {
- i+=3;
- ExpDate[1]=responseR[i];
- ExpDate[0]=responseR[i+1];
- return true;
- }
- }
- return false;
- }
- bool Get_Pan_From_Track2(uint8_t*responseR, uint8_t &responseRLength,bool &success)
- {
- memset(CardNumber, 0x00, sizeof(CardNumber));
- byte tmpSize=responseRLength;
- uint8_t count=0;
- uint8_t Q;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- if(responseR[i]==0x57 && responseR[i+10])
- {
- responseRLength=8;
- i+=2;
- while(count<responseRLength)
- {
- CardNumber[count++]=responseR[i++];
- }
- responseRLength=tmpSize;
- success=true;
- return true;
- }
- }
- success=false;
- return false;
- }
- bool Get_EXP_From_Track2(uint8_t*responseR, uint8_t &responseRLength,bool &success)
- {
- memset(ExpDate, 0x00, sizeof(ExpDate));
- uint8_t Q;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- Q=responseR[i];
- if((Q&0x10) && !(Q&0x20) && (Q&0x40) && (Q&0x80))
- {
- responseR[i]<<=4;
- responseR[i]>>=4;
- ExpDate[1]=responseR[i];
- i++;
- ExpDate[1] = (ExpDate[1] << 4)|(responseR[i]&0xF0)>>4;
- ExpDate[0] = responseR[i]&0x0F;
- i++;
- ExpDate[0] = (ExpDate[0] << 4)|(responseR[i]&0xF0)>>4;
- success=true;
- return true;
- }
- }
- success=false;
- return false;
- }
- void Get_NAME(uint8_t*responseR, uint8_t &responseRLength)
- {
- memset(NameOnCard, 0x00, sizeof(NameOnCard));
- byte tmpSize=responseRLength;
- uint8_t count=0;
- for(uint8_t i=0; i<responseRLength-1; i++)
- {
- if(responseR[i]==0x5F && responseR[i+1]==0x20)
- {
- responseRLength=responseR[i+2];
- i+=3;
- while(count<responseRLength)
- {
- NameOnCard[count++]=responseR[i++];
- }
- responseRLength=tmpSize;
- return;
- }
- }
- }
- void Read_AFL(uint8_t*responseR, uint8_t &responseRLength,bool &success)
- {
- uint8_t AFLCounter =0;
- uint8_t AFLStringSize = responseRLength/5;
- uint8_t AFLColomnSize = 5;
- uint8_t AFL[AFLStringSize][AFLColomnSize];
- for(uint8_t i = 0; i<AFLStringSize; i++)
- {
- for(uint8_t j = 0; j<AFLColomnSize;j++)
- {
- AFL[i][j] = responseR[AFLCounter++];
- }
- }
- for(uint8_t i = 0; i<AFLStringSize; i++)
- {
- responseRLength = GetResponse(AFL[i],5,responseR,success);
- if(Get_PAN(responseR,responseRLength))
- {
- if(Get_EXP(responseR,responseRLength))
- {
- Get_NAME(responseR,responseRLength);
- success=true;
- return;
- }
- }
- }
- success=false;
- }
- bool CHECK_PDOL(uint8_t*responseR,uint8_t responseRLength,bool &success)
- {
- int Q;
- for(uint8_t i =0; i<responseRLength-1; i++)
- {
- Q = ((uint8_t)responseR[i] << 8) | responseR[i+1];
- if(Q == 0x9F38)
- {
- success=true;
- return true;
- }
- }
- success=false;
- return false;
- }
- bool CHECK_AFL(uint8_t*responseR,uint8_t responseRLength,bool &success)
- {
- for(uint8_t i =0; i<responseRLength-1; i++)
- {
- 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)
- {
- success=true;
- return true;
- }
- }
- success=false;
- return false;
- }
- void array_to_string(uint8_t*arr, uint8_t arrsize, char*buf)
- {
- for (byte i = 0; i < arrsize; i++)
- {
- byte nib1 = (arr[i] >> 4) & 0x0F;
- byte nib2 = (arr[i] >> 0) & 0x0F;
- buf[i*2+0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
- buf[i*2+1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
- }
- buf[arrsize*2] = '\0';
- }
- void PrintAllData()
- {
- byte Q;
- byte count=0;
- char big[20]={0x00,};
- char small[16]={0x00,};
- char ExpMM[2];
- char ExpYY[2];
- if(NameOnCard[0]!=0x00){LD.printString_6x8(NameOnCard, 0, 0);}
- LD.printString_6x8(AppLabel, 0, 2);
- if(cardtype==2){count=10;}else{count=8;}
- LD.printString_6x8(AppLabel, 0, 2);
- 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);
- array_to_string(&ExpDate[0],1,ExpMM);
- array_to_string(&ExpDate[1],1,ExpYY);
- LD.printString_6x8(ExpMM, 0, 6);LD.printString_6x8("/", 12, 6);LD.printString_6x8(ExpYY, 18, 6);
- }
- void loop()
- {
- uint8_t * responseR = (uint8_t *)malloc(sizeof(uint8_t));
- uint8_t responseRLength=0;
- uint8_t apduSize=0;
- success = nfc.inListPassiveTarget();
- if(success)
- {
- LD.clearDisplay();
- LD.printString_12x16("!!GetCard!!", 0, 2);
- uint8_t apdu[] = {0x00, 0xA4, 0x04, 0x00, 0x0E, 0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00};
- Serial.print("APDU: ");
- nfc.PrintHexChar(apdu,sizeof(apdu));
- responseRLength = GetResponse (apdu,sizeof(apdu),responseR,success);
- Serial.print("Response: ");
- nfc.PrintHexChar(responseR,responseRLength);
- if(success)
- {
- uint8_t apdu[] = {0x00, 0xA4, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- Get_AID_Apdu(responseR,responseRLength,apdu,cardtype);
- Serial.print("APDU: ");
- nfc.PrintHexChar(apdu,sizeof(apdu));
- responseRLength = GetResponse (apdu,sizeof(apdu),responseR,success);
- Serial.print("Response: ");
- nfc.PrintHexChar(responseR,responseRLength);
- GetApplicationLabel(responseR,responseRLength);
- if(success)
- {
- if(CHECK_PDOL(responseR,responseRLength,success))
- {
- responseRLength=Get_PDOL(responseR,responseRLength,success);
- Serial.print("PDOL: ");
- nfc.PrintHexChar(responseR,responseRLength);
- responseRLength=PDOL_Generator(responseR,responseRLength);
- Serial.print("PDOL_GENERATOR: ");
- nfc.PrintHexChar(responseR,responseRLength);
- apduSize=7+responseRLength+1;
- uint8_t apdu[apduSize] = {0x80, 0xA8, 0x00, 0x00, 0x12, 0x83, responseRLength};
- Get_PDOL_Apdu(responseR,responseRLength,apdu);
- Serial.print("APDU: ");
- nfc.PrintHexChar(apdu,sizeof(apdu));
- responseRLength=GetResponse (apdu,apduSize,responseR,success);
- if(responseRLength<5)
- {
- LD.printString_12x16("PDOL_ERROR", 0, 2);
- return;
- }
- Serial.print("Response: ");
- nfc.PrintHexChar(responseR,responseRLength);
- }
- else
- {
- uint8_t apdu[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00};
- Serial.print("APDU: ");
- nfc.PrintHexChar(apdu,sizeof(apdu));
- responseRLength=GetResponse (apdu,sizeof(apdu),responseR,success);
- Serial.print("Response: ");
- nfc.PrintHexChar(responseR,responseRLength);
- }
- if(success)
- {
- if(CHECK_AFL(responseR,responseRLength,success))
- {
- responseRLength=Get_AFL(responseR,responseRLength,success);
- responseRLength=SFIGenerator(responseR,responseRLength);
- Serial.print("Response: ");
- nfc.PrintHexChar(responseR,responseRLength);
- Read_AFL(responseR,responseRLength,success);
- }
- else
- {
- if(Get_Pan_From_Track2(responseR, responseRLength,success))
- {
- if(Get_EXP_From_Track2(responseR, responseRLength,success))
- {
- Get_NAME(responseR,responseRLength);
- }
- }
- }
- }
- }
- }
- LD.clearDisplay();
- PrintAllData();
- if(success)
- {
- free(responseR);
- reallocCheck=NULL;
- cardtype=0;
- success=false;
- responseRLength=0;
- apduSize=0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement