MifareClassic


public final class MifareClassic
extends Object implements TagTechnology

java.lang.Object
   ↳ android.nfc.tech.MifareClassic


Provides access to MIFARE Classic properties and I/O operations on a Tag.

Acquire a MifareClassic object using get(Tag).

MIFARE Classic is also known as MIFARE Standard.

MIFARE Classic tags are divided into sectors, and each sector is sub-divided into blocks. Block size is always 16 bytes (BLOCK_SIZE. Sector size varies.

  • MIFARE Classic Mini are 320 bytes (SIZE_MINI), with 5 sectors each of 4 blocks.
  • MIFARE Classic 1k are 1024 bytes (SIZE_1K), with 16 sectors each of 4 blocks.
  • MIFARE Classic 2k are 2048 bytes (SIZE_2K), with 32 sectors each of 4 blocks.
  • MIFARE Classic 4k are 4096 bytes (SIZE_4K). The first 32 sectors contain 4 blocks and the last 8 sectors contain 16 blocks.

MIFARE Classic tags require authentication on a per-sector basis before any other I/O operations on that sector can be performed. There are two keys per sector, and ACL bits determine what I/O operations are allowed on that sector after authenticating with a key. and .

Three well-known authentication keys are defined in this class: KEY_DEFAULT, KEY_MIFARE_APPLICATION_DIRECTORY, KEY_NFC_FORUM.

  • KEY_DEFAULT is the default factory key for MIFARE Classic.
  • KEY_MIFARE_APPLICATION_DIRECTORY is the well-known key for MIFARE Classic cards that have been formatted according to the MIFARE Application Directory (MAD) specification.
  • KEY_NFC_FORUM is the well-known key for MIFARE Classic cards that have been formatted according to the NXP specification for NDEF on MIFARE Classic.

    Implementation of this class on a Android NFC device is optional. If it is not implemented, then MifareClassic will never be enumerated in Tag#getTechList. If it is enumerated, then all MifareClassic I/O operations will be supported, and Ndef#MIFARE_CLASSIC NDEF tags will also be supported. In either case, NfcA will also be enumerated on the tag, because all MIFARE Classic tags are also NfcA.

    Note: Methods that perform I/O operations require the Manifest.permission.NFC permission.

    Summary

    Constants

    int BLOCK_SIZE

    Size of a MIFARE Classic block (in bytes)

    int SIZE_1K

    Tag contains 16 sectors, each with 4 blocks.

    int SIZE_2K

    Tag contains 32 sectors, each with 4 blocks.

    int SIZE_4K

    Tag contains 40 sectors.

    int SIZE_MINI

    Tag contains 5 sectors, each with 4 blocks.

    int TYPE_CLASSIC

    A MIFARE Classic tag

    int TYPE_PLUS

    A MIFARE Plus tag

    int TYPE_PRO

    A MIFARE Pro tag

    int TYPE_UNKNOWN

    A MIFARE Classic compatible card of unknown type

    Fields

    public static final byte[] KEY_DEFAULT

    The default factory key.

    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY

    The well-known key for tags formatted according to the MIFARE Application Directory (MAD) specification.

    public static final byte[] KEY_NFC_FORUM

    The well-known key for tags formatted according to the NDEF on MIFARE Classic specification.

    Public methods

    boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key)

    Authenticate a sector with key A.

    boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key)

    Authenticate a sector with key B.

    int blockToSector(int blockIndex)

    Return the sector that contains a given block.

    void close()

    Disable I/O operations to the tag from this TagTechnology object, and release resources.

    void connect()

    Enable I/O operations to the tag from this TagTechnology object.

    void decrement(int blockIndex, int value)

    Decrement a value block, storing the result in the temporary block on the tag.

    static MifareClassic get(Tag tag)

    Get an instance of MifareClassic for the given tag.

    int getBlockCount()

    Return the total number of MIFARE Classic blocks.

    int getBlockCountInSector(int sectorIndex)

    Return the number of blocks in the given sector.

    int getMaxTransceiveLength()

    Return the maximum number of bytes that can be sent with transceive(byte).

    int getSectorCount()

    Return the number of MIFARE Classic sectors.

    int getSize()

    Return the size of the tag in bytes

    One of SIZE_MINI, SIZE_1K, SIZE_2K, SIZE_4K.

    Tag getTag()

    Get the Tag object backing this TagTechnology object.

    int getTimeout()

    Get the current transceive(byte) timeout in milliseconds.

    int getType()

    Return the type of this MIFARE Classic compatible tag.

    void increment(int blockIndex, int value)

    Increment a value block, storing the result in the temporary block on the tag.

    boolean isConnected()

    Helper to indicate if I/O operations should be possible.

    byte[] readBlock(int blockIndex)

    Read 16-byte block.

    void restore(int blockIndex)

    Copy from a value block to the temporary block.

    int sectorToBlock(int sectorIndex)

    Return the first block of a given sector.

    void setTimeout(int timeout)

    Set the transceive(byte) timeout in milliseconds.

    byte[] transceive(byte[] data)

    Send raw NfcA data to a tag and receive the response.

    void transfer(int blockIndex)

    Copy from the temporary block to a value block.

    void writeBlock(int blockIndex, byte[] data)

    Write 16-byte block.

    Inherited methods

    Constants

    BLOCK_SIZE

    Added in API level 10
    public static final int BLOCK_SIZE

    Size of a MIFARE Classic block (in bytes)

    Constant Value: 16 (0x00000010)

    SIZE_1K

    Added in API level 10
    public static final int SIZE_1K

    Tag contains 16 sectors, each with 4 blocks.

    Constant Value: 1024 (0x00000400)

    SIZE_2K

    Added in API level 10
    public static final int SIZE_2K

    Tag contains 32 sectors, each with 4 blocks.

    Constant Value: 2048 (0x00000800)

    SIZE_4K

    Added in API level 10
    public static final int SIZE_4K

    Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors contain 16 blocks.

    Constant Value: 4096 (0x00001000)

    SIZE_MINI

    Added in API level 10
    public static final int SIZE_MINI

    Tag contains 5 sectors, each with 4 blocks.

    Constant Value: 320 (0x00000140)

    TYPE_CLASSIC

    Added in API level 10
    public static final int TYPE_CLASSIC

    A MIFARE Classic tag

    Constant Value: 0 (0x00000000)

    TYPE_PLUS

    Added in API level 10
    public static final int TYPE_PLUS

    A MIFARE Plus tag

    Constant Value: 1 (0x00000001)

    TYPE_PRO

    Added in API level 10
    public static final int TYPE_PRO

    A MIFARE Pro tag

    Constant Value: 2 (0x00000002)

    TYPE_UNKNOWN

    Added in API level 10
    public static final int TYPE_UNKNOWN

    A MIFARE Classic compatible card of unknown type

    Constant Value: -1 (0xffffffff)

    Fields

    KEY_DEFAULT

    Added in API level 10
    public static final byte[] KEY_DEFAULT

    The default factory key.

    KEY_MIFARE_APPLICATION_DIRECTORY

    Added in API level 10
    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY

    The well-known key for tags formatted according to the MIFARE Application Directory (MAD) specification.

    KEY_NFC_FORUM

    Added in API level 10
    public static final byte[] KEY_NFC_FORUM

    The well-known key for tags formatted according to the NDEF on MIFARE Classic specification.

    Public methods

    authenticateSectorWithKeyA

    Added in API level 10
    public boolean authenticateSectorWithKeyA (int sectorIndex, 
                    byte[] key)

    Authenticate a sector with key A.

    Successful authentication of a sector with key A enables other I/O operations on that sector. The set of operations granted by key A key depends on the ACL bits set in that sector. For more information see the MIFARE Classic specification on http://www.nxp.com.

    A failed authentication attempt causes an implicit reconnection to the tag, so authentication to other sectors will be lost.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    sectorIndex int: index of sector to authenticate, starting from 0

    key byte: 6-byte authentication key

    Returns
    boolean true on success, false on authentication failure

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    authenticateSectorWithKeyB

    Added in API level 10
    public boolean authenticateSectorWithKeyB (int sectorIndex, 
                    byte[] key)

    Authenticate a sector with key B.

    Successful authentication of a sector with key B enables other I/O operations on that sector. The set of operations granted by key B depends on the ACL bits set in that sector. For more information see the MIFARE Classic specification on http://www.nxp.com.

    A failed authentication attempt causes an implicit reconnection to the tag, so authentication to other sectors will be lost.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    sectorIndex int: index of sector to authenticate, starting from 0

    key byte: 6-byte authentication key

    Returns
    boolean true on success, false on authentication failure

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    blockToSector

    Added in API level 10
    public int blockToSector (int blockIndex)

    Return the sector that contains a given block.

    Does not cause any RF activity and does not block.

    Parameters
    blockIndex int: index of block to lookup, starting from 0

    Returns
    int sector index that contains the block

    close

    Added in API level 10
    public void close ()

    Disable I/O operations to the tag from this TagTechnology object, and release resources.

    Also causes all blocked I/O operations on other thread to be canceled and return with IOException.

    Requires the Manifest.permission.NFC permission.

    Throws
    IOException

    connect

    Added in API level 10
    public void connect ()

    Enable I/O operations to the tag from this TagTechnology object.

    May cause RF activity and may block. Must not be called from the main application thread. A blocked call will be canceled with IOException by calling close() from another thread.

    Only one TagTechnology object can be connected to a Tag at a time.

    Applications must call close() when I/O operations are complete.

    Requires the Manifest.permission.NFC permission.

    Throws
    IOException

    decrement

    Added in API level 10
    public void decrement (int blockIndex, 
                    int value)

    Decrement a value block, storing the result in the temporary block on the tag.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to decrement, starting from 0

    value int: non-negative to decrement by

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    get

    Added in API level 10
    public static MifareClassic get (Tag tag)

    Get an instance of MifareClassic for the given tag.

    Does not cause any RF activity and does not block.

    Returns null if MifareClassic was not enumerated in Tag#getTechList. This indicates the tag is not MIFARE Classic compatible, or this Android device does not support MIFARE Classic.

    Parameters
    tag Tag: an MIFARE Classic compatible tag

    Returns
    MifareClassic MIFARE Classic object

    getBlockCount

    Added in API level 10
    public int getBlockCount ()

    Return the total number of MIFARE Classic blocks.

    Does not cause any RF activity and does not block.

    Returns
    int total number of blocks

    getBlockCountInSector

    Added in API level 10
    public int getBlockCountInSector (int sectorIndex)

    Return the number of blocks in the given sector.

    Does not cause any RF activity and does not block.

    Parameters
    sectorIndex int: index of sector, starting from 0

    Returns
    int number of blocks in the sector

    getMaxTransceiveLength

    Added in API level 14
    public int getMaxTransceiveLength ()

    Return the maximum number of bytes that can be sent with transceive(byte).

    Returns
    int the maximum number of bytes that can be sent with transceive(byte).

    getSectorCount

    Added in API level 10
    public int getSectorCount ()

    Return the number of MIFARE Classic sectors.

    Does not cause any RF activity and does not block.

    Returns
    int number of sectors

    getSize

    Added in API level 10
    public int getSize ()

    Return the size of the tag in bytes

    One of SIZE_MINI, SIZE_1K, SIZE_2K, SIZE_4K. These constants are equal to their respective size in bytes.

    Does not cause any RF activity and does not block.

    Returns
    int size in bytes

    getTag

    Added in API level 10
    public Tag getTag ()

    Get the Tag object backing this TagTechnology object.

    Returns
    Tag the Tag backing this TagTechnology object.

    getTimeout

    Added in API level 14
    public int getTimeout ()

    Get the current transceive(byte) timeout in milliseconds.

    Requires the Manifest.permission.NFC permission.

    Returns
    int timeout value in milliseconds

    Throws
    SecurityException if the tag object is reused after the tag has left the field

    getType

    Added in API level 10
    public int getType ()

    Return the type of this MIFARE Classic compatible tag.

    One of TYPE_UNKNOWN, TYPE_CLASSIC, TYPE_PLUS or TYPE_PRO.

    Does not cause any RF activity and does not block.

    Returns
    int type

    increment

    Added in API level 10
    public void increment (int blockIndex, 
                    int value)

    Increment a value block, storing the result in the temporary block on the tag.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to increment, starting from 0

    value int: non-negative to increment by

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    isConnected

    Added in API level 10
    public boolean isConnected ()

    Helper to indicate if I/O operations should be possible.

    Returns true if connect() has completed, and close() has not been called, and the Tag is not known to be out of range.

    Does not cause RF activity, and does not block.

    Returns
    boolean true if I/O operations should be possible

    readBlock

    Added in API level 10
    public byte[] readBlock (int blockIndex)

    Read 16-byte block.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to read, starting from 0

    Returns
    byte[] 16 byte block

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    restore

    Added in API level 10
    public void restore (int blockIndex)

    Copy from a value block to the temporary block.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to copy from

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    sectorToBlock

    Added in API level 10
    public int sectorToBlock (int sectorIndex)

    Return the first block of a given sector.

    Does not cause any RF activity and does not block.

    Parameters
    sectorIndex int: index of sector to lookup, starting from 0

    Returns
    int block index of first block in sector

    setTimeout

    Added in API level 14
    public void setTimeout (int timeout)

    Set the transceive(byte) timeout in milliseconds.

    The timeout only applies to transceive(byte) on this object, and is reset to a default value when close() is called.

    Setting a longer timeout may be useful when performing transactions that require a long processing time on the tag such as key generation.

    Requires the Manifest.permission.NFC permission.

    Parameters
    timeout int: timeout value in milliseconds

    Throws
    SecurityException if the tag object is reused after the tag has left the field

    transceive

    Added in API level 10
    public byte[] transceive (byte[] data)

    Send raw NfcA data to a tag and receive the response.

    This is equivalent to connecting to this tag via NfcA and calling NfcA#transceive. Note that all MIFARE Classic tags are based on NfcA technology.

    Use getMaxTransceiveLength() to retrieve the maximum number of bytes that can be sent with transceive(byte).

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    data byte

    Returns
    byte[]

    Throws
    IOException

    transfer

    Added in API level 10
    public void transfer (int blockIndex)

    Copy from the temporary block to a value block.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to copy to

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled

    writeBlock

    Added in API level 10
    public void writeBlock (int blockIndex, 
                    byte[] data)

    Write 16-byte block.

    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 IOException if close() is called from another thread.

    Requires the Manifest.permission.NFC permission.

    Parameters
    blockIndex int: index of block to write, starting from 0

    data byte: 16 bytes of data to write

    Throws
    TagLostException if the tag leaves the field
    IOException if there is an I/O failure, or the operation is canceled