#include #include #include #include "SoftwareSerial8e1.h" #define STATUS_LED 13 #define READER_VCC #define READER_RST 3 #define READER_CLK #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; int emulatorAtrBaudRate = -1; int emulatorCommandBaudRate = -1; int digitalPinToInterrupt(int pin) { if (pin == 2) { return INT0; } else if (pin == 3) { return INT1; } return -1; } void emulatorComputeBaudRate() { emulatorAtrBaudRate = 9600; emulatorCommandBaudRate = 13171; } void emulatorSend(const uint8_t* atr, size_t size, int baudRate) { SoftwareSerial8e1 emulatorSerial(5, READER_IO); emulatorSerial.begin(baudRate); emulatorSerial.write(atr, size); emulatorSerial.end(); } bool emulatorRead(uint8_t* data, size_t* size, unsigned long timeout, int baudRate) { unsigned long end = micros() + timeout; SoftwareSerial8e1 emulatorSerial(READER_IO, 5); emulatorSerial.begin(baudRate); while (emulatorSerial.available() < 4 && (timeout == 0 || end >= micros())); if (timeout != 0 && end < micros()) { return false; } int available = 0; do { available = emulatorSerial.available(); delayMicroseconds(2 * 1000000 / baudRate); } while (available != emulatorSerial.available()); *size = *size > available ? available : *size; emulatorSerial.readBytes((char*)data, *size); emulatorSerial.end(); return true; } void readerResetAtr() { for (size_t i = 0; i < sizeof(readerAtr); ++i) { readerAtr[i] = 0; } readerAtrSize = 0; } void emulatorOnReset() { Serial.println("Reset"); emulatorComputeBaudRate(); emulatorSend(readerAtr, readerAtrSize, emulatorAtrBaudRate); } void setup() { Serial.begin(9600); Serial.println("Initializing..."); pinMode(READER_RST, INPUT); pinMode(READER_IO, OUTPUT); digitalWrite(READER_IO, HIGH); pinMode(STATUS_LED, OUTPUT); digitalWrite(STATUS_LED, LOW); attachInterrupt(digitalPinToInterrupt(READER_RST), emulatorOnReset, RISING); Serial.println("Initialized"); readerResetAtr(); } void loop() { if (readerAtrSize == 0) { if (cardReader.cardInserted()) { readerAtrSize = cardReader.activate(readerAtr, sizeof(readerAtr)); cardReader.dumpHEX(readerAtr, readerAtrSize); cardReader.deactivate(); digitalWrite(STATUS_LED, HIGH); } } else { if (!cardReader.cardInserted()) { readerResetAtr(); digitalWrite(STATUS_LED, LOW); } else { uint8_t data[42]; size_t dataSize = sizeof(data) - 2; if (emulatorRead(data, &dataSize, 100000, emulatorCommandBaudRate)) { delayMicroseconds(2300); // data[dataSize++] = 0x6d; // data[dataSize++] = 0x00; // emulatorSend(data, dataSize, emulatorCommandBaudRate); const uint8_t resp[] = {data[0], data[dataSize - 1]}; emulatorSend(resp, sizeof(resp), emulatorCommandBaudRate); for (int i = 0; i < dataSize; ++i) { Serial.print((int) data[i]); Serial.print(' '); } Serial.println(); } } } }