import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class NfcTest {
    private static final String DEV_PATH = "/dev/nfc_dev";
    private static final int BUF_SIZE = 256;

    public static void main(String[] args) {
        String dev = (args.length > 0) ? args[0] : DEV_PATH;
        try (FileInputStream fis = new FileInputStream(dev)) {
            System.out.println("NFC test started on " + dev + ", waiting for card...");
            byte[] buf = new byte[BUF_SIZE];
            while (true) {
                int n = fis.read(buf);
                if (n < 0) {
                    System.out.println("EOF reached");
                    break;
                }
                if (n < 4) {
                    System.out.println("short read: " + n + " bytes");
                    continue;
                }

                int datatype = buf[0] & 0xFF;
                int status   = buf[1] & 0xFF;
                int dataLen  = ((buf[2] & 0xFF) << 8) | (buf[3] & 0xFF);
                if (n < 4 + dataLen) {
                    dataLen = n - 4;
                }

                String ts = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
                switch (datatype) {
                    case 1:
                        System.out.printf("[%s] ATQA  (type=1 status=%d len=%d): %02X %02X%n",
                                ts, status, dataLen, buf[4] & 0xFF, (dataLen > 1 ? buf[5] & 0xFF : 0));
                        break;
                    case 2:
                        System.out.printf("[%s] SAK   (type=2 status=%d len=%d): %02X%n",
                                ts, status, dataLen, buf[4] & 0xFF);
                        break;
                    case 0:
                        StringBuilder uid = new StringBuilder();
                        for (int i = 0; i < dataLen; i++) {
                            if (i > 0) uid.append(" ");
                            uid.append(String.format("%02X", buf[4 + i] & 0xFF));
                        }
                        System.out.printf("[%s] UID   (type=0 status=%d len=%d): %s%n",
                                ts, status, dataLen, uid);
                        break;
                    default:
                        StringBuilder hex = new StringBuilder();
                        for (int i = 0; i < dataLen; i++) {
                            if (i > 0) hex.append(" ");
                            hex.append(String.format("%02X", buf[4 + i] & 0xFF));
                        }
                        System.out.printf("[%s] UNKNOWN (type=%d status=%d len=%d): %s%n",
                                ts, datatype, status, dataLen, hex);
                        break;
                }
            }
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(1);
        }
    }
}
