Nexus 4 read Mifare Classic card UID

2020-05-06 17:11发布

问题:

Currently we are developing NFC applications for Android.  Our experience

  • Developed POS NFC control system using NXP PN5xx chips for control of Mifare Classic (1K) and CEPAS standard

  • Developed Android NFC control system for MiFareClassic and Ultralight C in Galaxy Nexus (using NXP NFC chipset)

  • Developed Android NFC control system for Ultralight C in Nexus 4

Our challenge: we want to control MiFareClassic 1K card in our POS machine (with NXP chip) and in new Android tablets (with Broadcom chip), we already have the installed card base and can not replace them.

 - We know Nexus 4 has changed the NFC chip, now it can not read/write any Mifare classic card block except UID.

 - Our code detects Mifare classic card as NfcA type. NfcA has a method called transceive(byte[] data) to Send raw NFC-A commands to the tag and receive the response.

 - Our problem is we need to know what code to send to the device to read the UID, other people online say they can do it but no methodology can be found

Currently we always get an error: android.nfc.TagLostException: Tag was lost.

Thanks for your answer.

回答1:

You can call getId() on the Tag object in the Intent. This will return the ID of the tag (which, in the case of MIFARE Classic, may be a 4- or 7-byte unique ID, a random ID or a fixed non-unique 4-byte ID; depending on the exact MIFARE Classic product). There is no need to call connect() on NfcA (and no possibility to do anything meaningful).

Please, note that this will not work on the Samsung Galaxy S4. That phone will not dispatch an NFC intent when a MIFARE tag is tapped. Instead, it will display an error message on the screen stating that the phone is incompatible with this tag and then ignore the tag.

UPDATE: On an S4 running Android 4.4 KitKat, you can use the NFC Reader Mode to get access to such details as card UID, also for MIFARE Classic tags.



回答2:

You cannot talk to the Mifare Classic chip using the Broadcom Chip found in the Nexus 4.

You can read the UID. That is the part of the Mifare Classic protocol that is compatible to NfcA.

Anything more than that requires an implementation of the Mifare Classic Crypto1 Algorithm which the Broadcom chip (and lots of other upcoming NFC-Controllers) lacks.

Running Crypto1 in software (sourcecode is on wikipedia) is also not an option because the authentication request for Mifare Classic would require the chip to send out frames that are not compatible to NfcA.



回答3:

Well, with the dispatchers already set, you can use this in your activity:

    private String serialId = "";

@Override
    public void onNewIntent(Intent intent) {
    String action = intent.getAction();
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {          
        try {
            byte[] tagId = tag.getId();
            serialId = bytesToHex(tagId);
            Log.d("[ReadCardTools]", "Serial Number: " + result);
        } catch (NullPointerException ex) {
            ex.printStackTrace();
            serialId = "ERROR";
        }
    } else {
        Toast.makeText(this, "This tag is not supported. Action: " + action, Toast.LENGTH_LONG).show();
    }
}

private String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[(j * 2) + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}