简体   繁体   中英

How to send ATQA and SEL to Mifare Classic 1k

According to the documentation, before a read/write can occur, I need to send REQA followed by SELECT for anti-collision. But I couldn't find any complete example code, code sequence performing this. Every one starts with authenticate in onTagDiscovered , and starts reading/writing.

So my question is, 1. does Android performs its own REQA/SEL on its own under the hood? 2. If i wanted to, how do I perform REQA and SEL on my own?

I have come up with a sample code, based on the code here

try {
            byte[] reqa = new byte[1];
            reqa[0] = 0x26;
            Log.e(TAG, "Sending REQA: " + bytesToHex(reqa));
            mifareTag.transceive(reqa);                
            Log.e(TAG, bytesToHex(mifareTag.transceive(reqa)));

            byte[] sel = new byte[9];
            sel[0] = (byte) 0x93;
            sel[1] = (byte) 0x70;
            System.arraycopy(uid, uid.length - 4, sel, 2, 4);
            sel[6] = (byte) (sel[2] ^ sel[3] ^ sel[4] ^ sel[5]);

            java.util.zip.CRC32 x = new java.util.zip.CRC32();
            x.update(sel);
            long crc32 = x.getValue();

            sel[7] = (byte) crc32;
            sel[8] = (byte) (crc32 >> 8);

            Log.e(TAG, "CRC: " + Long.toHexString(crc32));
            Log.e(TAG, "Sending SEL: " + bytesToHex(sel));

            Log.e(TAG, bytesToHex(mifareTag.transceive(sel)));
            if (mifareTag.transceive(cmd) != null) {
                Log.e(TAG, "NfcA Tag transcieve:auth success");
                return true;
            }
        } catch (Exception ex) {
            Log.e(TAG, "NfcA Tag transcieve:auth failed with exception !", ex);
            return false;
        }

But the problem is, with this code, what I'm receiving back is weird data.

10-22 11:04:13.465 30687-30734/com.mfreader E/RfidReader: Sending REQA: 26
10-22 11:04:13.492 30687-30734/com.mfreader E/RfidReader: B2007D9BD20804000215671E0D8B811D
10-22 11:04:13.492 30687-30734/com.mfreader E/RfidReader: CRC: a247ff86
10-22 11:04:13.493 30687-30734/com.mfreader E/RfidReader: Sending SEL: 93701A2E7D9BD286FF
10-22 11:04:13.519 30687-30734/com.mfreader E/RfidReader: B2007D9BD20804000215671E0D8B811D
10-22 11:04:13.602 30687-30734/com.mfreader E/RfidReader: NfcA Tag transcieve:auth failed with exception !
    java.io.IOException: Transceive failed
        at android.nfc.TransceiveResult.getResponseOrThrow(TransceiveResult.java:52)
        at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:151)
        at android.nfc.tech.NfcA.transceive(NfcA.java:145)

The returned value is Sect#0Block#0 but the first 2 bytes replaced with B200 instead of 1A2E of the UID. And the succeeding Auth fails, which otherwise fails only intermittently (which is what i'm trying to solve)!

Not sure what i'm doing wrong, any help?

  1. does Android performs its own REQA/SEL on its own under the hood?

Yes

  1. If I wanted to, how do I perform REQA and SEL on my own?
  /**
 * Send raw NFC-A commands to the tag and receive the response.
 *
 * <p>Applications must not append the EoD (CRC) to the payload,
 * it will be automatically calculated.
 * <p>Applications must only send commands that are complete bytes,
 * for example a SENS_REQ is not possible (these are used to
 * manage tag polling and initialization).
 *
 * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
 * that can be sent with {@link #transceive}.
 *
 * <p>This is an I/O operation and will block until complete. It must
 * not be called from the main application thread. A blocked call will be canceled with
 * {@link IOException} if {@link #close} is called from another thread.
 *
 * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
 *
 * @param data bytes to send
 * @return bytes received in response
 * @throws TagLostException if the tag leaves the field
 * @throws IOException if there is an I/O failure, or this operation is canceled
 */
public byte[] transceive(byte[] data) throws IOException {
    return transceive(data, true);
}

You can select tag by method mifareTag.connect() , after authenticating with android methods from android docs you can write and read. https://developer.android.com/reference/android/nfc/tech/MifareClassic What means error 'B2' do you got it somewhere in documentation?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM