diff --git a/Audio/mixkit-gaming-lock-2848.wav b/Audio/mixkit-gaming-lock-2848.wav new file mode 100644 index 0000000..d079479 Binary files /dev/null and b/Audio/mixkit-gaming-lock-2848.wav differ diff --git a/firmware.ino b/firmware.ino new file mode 100644 index 0000000..b6f863c --- /dev/null +++ b/firmware.ino @@ -0,0 +1,104 @@ +#include + +#include +#include +#include + +PN532_I2C pn532i2c(Wire); +PN532 nfc(pn532i2c); + +#define Serial USBSerial + +#include + +uint8_t _prevIDm[8]; +unsigned long _prevTime; + +void setup(void) +{ + delay(1000); + Serial.begin(115200); + Serial.println("Hello!"); + Wire.setPins(4, 5); + + nfc.begin(); + + uint32_t versiondata = nfc.getFirmwareVersion(); + if (!versiondata) + { + Serial.print("Didn't find PN53x board"); + while (1) {delay(10);}; // halt + } + + // Got ok data, print it out! + Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); + Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); + Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); + + // Set the max number of retry attempts to read from a card + // This prevents us from waiting forever for a card, which is + // the default behaviour of the PN532. + nfc.setPassiveActivationRetries(0xFF); + nfc.SAMConfig(); + + memset(_prevIDm, 0, 8); +} + +void loop(void) +{ + uint8_t ret; + uint16_t systemCode = 0xFFFF; + uint8_t requestCode = 0x00; // System Code request + uint8_t idm[8]; + uint8_t pmm[8]; + uint16_t systemCodeResponse; + + // Wait for an FeliCa type cards. + // When one is found, some basic information such as IDm, PMm, and System Code are retrieved. + Serial.print("F"); + ret = nfc.felica_Polling(systemCode, requestCode, idm, pmm, &systemCodeResponse, 5); + + if (ret == 1) { + if ( memcmp(idm, _prevIDm, 8) == 0 ) { + if ( (millis() - _prevTime) < 3000 ) { + delay(5); + return; + } + } + + Serial.println("\nFound a Felica card!"); + printUid(idm, 8); + + memcpy(_prevIDm, idm, 8); + _prevTime = millis(); + return; + } + + Serial.print("M"); + uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID + uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) + + if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 5)) { + // Check if the same card is present + if (memcmp(uid, _prevIDm, uidLength) == 0 && (millis() - _prevTime) < 3000) { + delay(5); + return; + } + + Serial.println("\nFound a MIFARE card!"); + printUid(uid, uidLength); + + memcpy(_prevIDm, uid, uidLength); + _prevTime = millis(); + return; + } +} + +void printUid(uint8_t* uid, uint8_t uidLength) { + Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes"); + Serial.print("UID Value: "); + for (uint8_t i = 0; i < uidLength; i++) { + Serial.print(uid[i], HEX); + } + Serial.println(""); +} diff --git a/receiver.py b/receiver.py new file mode 100644 index 0000000..094415c --- /dev/null +++ b/receiver.py @@ -0,0 +1,65 @@ +from pathlib import Path +import time +import serial +import re +from playsound import playsound +from pynput.keyboard import Key, Controller + +keyboard = Controller() + +# Configure your serial port and baud rate +SERIAL_PORT = 'COMx' # Replace 'COMx' with your serial port (e.g., 'COM3' on Windows or '/dev/ttyUSB0' on Linux) +# SERIAL_PORT = '/dev/ttyACM0' +BAUD_RATE = 115200 +PATH = Path('C:/MUGS/felica.txt') +# PATH = Path('/tmp/felica.txt') + +AUDIO_EFFECT = Path(__file__).parent / 'Audio/tofu.wav' + +def parse_uid(data): + """ + Parse the UID from the serial data. + """ + uid_value_match = re.search(r'UID Value: ([0-9A-F]+)', data) + + if uid_value_match: + uid = uid_value_match.group(1) + + # If UID is not 8 bytes, pad it with zeros + if len(uid) < 16: + uid = uid.zfill(16) + + # If the UID Doesn't start with 01 2E, set it to 01 2E + if uid[:4] != '012E': + uid = '012E' + uid[4:] + + # Write the UID to the file + print(f"UID: {uid}") + PATH.write_text(uid) + + # Play audio effect + playsound(str(AUDIO_EFFECT)) + + # Press ENTER button + keyboard.press(Key.enter) + time.sleep(0.5) + keyboard.release(Key.enter) + + return uid + + +if __name__ == "__main__": + ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1) + print(f"Listening on {SERIAL_PORT}...") + + try: + while True: + if ser.in_waiting > 0: + line = ser.readline().decode('utf-8', errors='replace').strip() + print(line) + parse_uid(line) + + except KeyboardInterrupt: + print("Exiting...") + finally: + ser.close() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..66e805c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pyserial +playsound +pynput \ No newline at end of file