#include #include #include #include "SoftwareSerial8e1.h" #define STATUS_LED 13 #define READER_VCC #define READER_RST 4 #define READER_CLK 3 #define READER_GND #define READER_VPP #define READER_IO 2 #define CARD_VCC 11 #define CARD_RST 7 #define CARD_CLK 9 #define CARD_GND #define CARD_VPP #define CARD_IO 10 #define CARD_PRE 12 SmartCardReader cardReader(CARD_IO, CARD_RST, CARD_VCC, CARD_PRE, CARD_CLK, false); uint8_t readerAtr[MAX_ATR_BYTES]; int readerAtrSize = 0; //SoftwareSerial8e1 emulatorSerial(READER_IO, 5); bool isResetUp; int baudRate = -1; int emulatorAtrEtu = -1; bool emulatorIoData = false; #ifndef digitalPinToInterrupt int digitalPinToInterrupt(int pin) { if (pin == 2) { return INT0; } else if (pin == 3) { return INT1; } return -1; } #endif void emulatorComputeEtu() { baudRate = 9600; emulatorAtrEtu = 1000000 / baudRate; } void emulatorSendByte(char byte, int etu) { unsigned long nextBitTime = micros() + (2 * etu); digitalWrite(READER_IO, HIGH); int bitNumber = 0; int parity = 0; while (bitNumber < 11) { if (nextBitTime <= micros()) { if (bitNumber == 0) { digitalWrite(READER_IO, LOW); } else if (bitNumber < 9) { int a = bitRead(byte, bitNumber - 1); parity += a; digitalWrite(READER_IO, a); } else if (bitNumber == 9) { digitalWrite(READER_IO, parity % 2); } else if (bitNumber == 10) { digitalWrite(READER_IO, HIGH); break; } nextBitTime += etu; ++bitNumber; } } } void emulatorSend(const uint8_t* atr, size_t size, int etu) { pinMode(5, OUTPUT); digitalWrite(5, HIGH); pinMode(READER_IO, OUTPUT); for (int i = 0; i < size; ++i) { emulatorSendByte(atr[i], etu); delayMicroseconds(4*etu); } digitalWrite(READER_IO, LOW); pinMode(READER_IO, INPUT); digitalWrite(5, LOW); } uint8_t emulatorReadByte(int etu) { // while (digitalRead(READER_IO)); unsigned long nextBitTime = micros() + (3 * etu / 2); uint8_t byte = 0; int bitNumber = 0; int parity = 0; while (bitNumber < 10) { if (nextBitTime <= micros()) { if (bitNumber < 8) { int bit = digitalRead(READER_IO); bitWrite(byte, bitNumber, bit); } else if (bitNumber == 8) { int parity = digitalRead(READER_IO); } else if (bitNumber == 9) { break; } nextBitTime += etu; ++bitNumber; } } return byte; } void emulatorReadCommand(int etu) { pinMode(READER_IO, INPUT); uint8_t cla = emulatorReadByte(etu); uint8_t ins = emulatorReadByte(etu); uint8_t p1 = emulatorReadByte(etu); uint8_t p2 = emulatorReadByte(etu); Serial.print((int)cla); Serial.print(' '); Serial.print((int)ins); Serial.print(' '); Serial.print((int)p1); Serial.print(' '); Serial.println((int)p2); // pinMode(READER_IO, OUTPUT); } void emulatorSetupIoInterrupt() { attachInterrupt(digitalPinToInterrupt(READER_IO), emulatorOnIoInterrupt, FALLING); } void emulatorOnIoInterrupt() { detachInterrupt(digitalPinToInterrupt(READER_IO)); emulatorIoData = true; } void readerResetAtr() { for (size_t i = 0; i < sizeof(readerAtr); ++i) { readerAtr[i] = 0; } readerAtrSize = 0; } void setup() { Serial.begin(9600); Serial.println("Initializing..."); pinMode(READER_CLK, INPUT); pinMode(READER_RST, INPUT); pinMode(READER_IO, OUTPUT); digitalWrite(READER_IO, HIGH); pinMode(STATUS_LED, OUTPUT); digitalWrite(STATUS_LED, LOW); isResetUp = digitalRead(READER_RST); Serial.println("Initialized"); readerResetAtr(); } void loop() { // if (emulatorIoData) // { // emulatorIoData = false; // uint8_t b = emulatorReadCommand(12171); // emulatorSetupIoInterrupt(); // Serial.println() // } if (readerAtrSize == 0) { if (cardReader.cardInserted()) { readerAtrSize = cardReader.activate(readerAtr, sizeof(readerAtr)); cardReader.dumpHEX(readerAtr, readerAtrSize); cardReader.deactivate(); digitalWrite(STATUS_LED, HIGH); } } else { int resetStatus = digitalRead(READER_RST); if (!cardReader.cardInserted()) { readerResetAtr(); digitalWrite(STATUS_LED, LOW); } else if (!isResetUp && resetStatus) { Serial.println("Reset"); emulatorComputeEtu(); emulatorSend(readerAtr, readerAtrSize, emulatorAtrEtu); int baudRate = 12171; int etu = 1000000 / baudRate; size_t dataSize = 0; uint8_t data[42]; { SoftwareSerial8e1 emulatorSerial(READER_IO, 5); emulatorSerial.begin(baudRate); while (emulatorSerial.available() < 8); dataSize = emulatorSerial.available(); emulatorSerial.readBytes((char *) data, dataSize); emulatorSerial.end(); } delayMicroseconds(1000); { SoftwareSerial8e1 emulatorSerial(5, READER_IO); emulatorSerial.begin(baudRate); const uint8_t resp[] = {0x90, 0x00}; emulatorSerial.write(resp, sizeof(resp)); emulatorSerial.end(); } for (int i = 0; i < dataSize; ++i) { Serial.print((int) data[i]); Serial.print(' '); } Serial.println(); // emulatorSend(resp, sizeof(resp), etu); // emulatorSetupIoInterrupt(); // for (size_t i = 0; i < readerAtrSize; ++i) // { // emulatorSerial.write(readerAtr[i]); // } // while (1) // { //// delayMicroseconds(10000); // bool has = false; // while (emulatorSerial.available()) // { // Serial.print((int) emulatorSerial.read()); // Serial.print(' '); // has = true; // } // if (has) // { // Serial.println(); // const uint8_t resp[] = {0x90, 0x00}; // emulatorSendAtr(resp, sizeof(resp), 12171); // emulatorSerial.begin(12171); //// emulatorSerial.write((uint8_t)0x90); //// emulatorSerial.write((uint8_t)0x00); // } // } // while (true) // { // emulatorReadCommand(12171); // } } isResetUp = resetStatus; } }