Class MifareCard
A Mifare card class Supports Mifare Classic 1K and 4K Also supports Mifare Plus 2K and 4K operating in SL1
public class MifareCard
- Inheritance
-
MifareCard
Constructors
MifareCard(CardTransceiver, byte)
Constructor for Mifarecard
public MifareCard(CardTransceiver rfid, byte target)
Parameters
rfid
CardTransceiverA card transceiver class
target
byteThe target number as some card readers attribute one
Properties
BlockNumber
The block number to authenticate or read or write
public byte BlockNumber { get; set; }
Property Value
Capacity
The storage capacity
public MifareCardCapacity Capacity { get; set; }
Property Value
Command
The command to execute on the card
public MifareCardCommand Command { get; set; }
Property Value
Data
The Data which has been read or to write for the specific block
public byte[] Data { get; set; }
Property Value
- byte[]
DefaultBlocksNdefKeyA
Default block Key A for NDEF card
public static SpanByte DefaultBlocksNdefKeyA { get; }
Property Value
Remarks
See https://www.nxp.com/docs/en/application-note/AN10787.pdf for more information
DefaultFirstBlockNdefKeyA
Default Mifare Application Directory block Key A for NDEF card The MAD is in the first sector on all cards and also sector 16 on 2K and 4K cards
public static SpanByte DefaultFirstBlockNdefKeyA { get; }
Property Value
Remarks
See https://www.nxp.com/docs/en/application-note/AN10787.pdf for more information
DefaultKeyA
Default Key A
public static SpanByte DefaultKeyA { get; }
Property Value
DefaultKeyB
Default Key B
public static SpanByte DefaultKeyB { get; }
Property Value
KeyA
Key A Used for encryption/decryption
public byte[]? KeyA { get; set; }
Property Value
- byte[]
KeyB
Key B Used for encryption/decryption
public byte[]? KeyB { get; set; }
Property Value
- byte[]
SerialNumber
UUID is the Serial Number, called MAC sometimes
public byte[]? SerialNumber { get; set; }
Property Value
- byte[]
Target
The tag number detected by the reader, only 1 or 2
public byte Target { get; set; }
Property Value
Methods
BlockAccess(byte, byte[])
Get the block access information
public AccessType BlockAccess(byte blockNumber, byte[] sectorData)
Parameters
Returns
- AccessType
The access type rights
BlockNumberToBlockGroup(byte)
Determine the block group corresponding to a block number
public static byte BlockNumberToBlockGroup(byte blockNumber)
Parameters
blockNumber
byteblock number
Returns
- byte
block group
BlockNumberToSector(byte)
Determine the sector number corresponding to a particular block number
public static byte BlockNumberToSector(byte blockNumber)
Parameters
blockNumber
byteblock number
Returns
- byte
sector number
EncodeDefaultSectorAndBlockTailer()
Encode with default value the access sector and tailer blocks
public Triplet EncodeDefaultSectorAndBlockTailer()
Returns
EncodeSectorAndBlockTailer(AccessSector, AccessType[])
Encode the desired access for the full sector including the block tailer
public Triplet EncodeSectorAndBlockTailer(AccessSector accessSector, AccessType[] accessTypes)
Parameters
accessSector
AccessSectorThe access desired
accessTypes
AccessType[]An array of 3 AccessType determining access of each block
Returns
- Triplet
The 3 bytes encoding the rights
EncodeSectorAndClockTailer(AccessSector, AccessType[])
Encode the desired access for the full sector including the block tailer
[Obsolete("deprecated, use EncodeSectorAndBlockTailer instead")]
public Triplet EncodeSectorAndClockTailer(AccessSector accessSector, AccessType[] accessTypes)
Parameters
accessSector
AccessSectorThe access desired
accessTypes
AccessType[]An array of 3 AccessType determining access of each block
Returns
- Triplet
The 3 bytes encoding the rights
EncodeSectorTailer(AccessSector)
Get the sector tailer bytes for a specific access sector configuration
public Triplet EncodeSectorTailer(AccessSector accessSector)
Parameters
accessSector
AccessSectorthe access sector
Returns
- Triplet
the 3 bytes for configuration
EncodeSectorTailer(byte, AccessType)
Encode the sector tailer access type for a specific block
public Triplet EncodeSectorTailer(byte blockNumber, AccessType accessType)
Parameters
blockNumber
byteThe block sector to encode
accessType
AccessTypeThe access type to encode
Returns
- Triplet
The encoded sector tailer for the specific block
EraseSector(SpanByte, SpanByte, byte, bool, bool)
Erase one sector
public bool EraseSector(SpanByte newKeyA, SpanByte newKeyB, byte sector, bool authenticateWithKeyA, bool resetAccessBytes)
Parameters
newKeyA
SpanByteThe new key A, empty to use current one
newKeyB
SpanByteThe new key B, empty to use current one
sector
byteThe sector number. Refer to Mifare documentation to understand how blocks work especially for Mifare 2K and 4K
authenticateWithKeyA
boolTrue to authenticate with current Key A, false to authenticate with Key B
resetAccessBytes
boolTrue to reset all the access bytes
Returns
- bool
True if success
Remarks
Sector 0 can't be fully erase, only the blocks 1 and 2 will be erased
FormatNdef(SpanByte)
Format the Card to NDEF
public bool FormatNdef(SpanByte keyB = default)
Parameters
keyB
SpanByteThe key B to be used for formatting, if empty, will use the default key B
Returns
- bool
True if success
Remarks
All sectors are configured as NFC Forum sectors
GetNumberBlocks()
Get the number of blocks for a specific sector
public int GetNumberBlocks()
Returns
- int
The number of blocks for this specific sector
GetNumberBlocks(byte)
Get the number of blocks for a specific sector
public byte GetNumberBlocks(byte sectorNumber)
Parameters
sectorNumber
byteInput sector number
Returns
- byte
The number of blocks for this specific sector
GetNumberSectors()
Get the number of sectors
public int GetNumberSectors()
Returns
IsFormattedNdef()
Check if the card formated to NDEF
public bool IsFormattedNdef()
Returns
- bool
True if NDEF formatted
Remarks
It will only check the first 2 block of the first sector and that the GPB is set properly
IsSectorBlock(byte)
Is it a block sector?
public bool IsSectorBlock(byte blockNumber)
Parameters
blockNumber
byteInput block number
Returns
- bool
True if it is a sector block
ReselectCard()
Select the card. Needed if authentication or read/write failed
public bool ReselectCard()
Returns
- bool
True if success
RunMifareCardCommand()
Run the last setup command. In case of reading bytes, they are automatically pushed into the Data property
public int RunMifareCardCommand()
Returns
- int
-1 if the process fails otherwise the number of bytes read
SectorTailerAccess(byte, byte[])
Get the sector tailer access information
public AccessSector SectorTailerAccess(byte blockNumber, byte[] sectorData)
Parameters
Returns
- AccessSector
the access sector rights
SectorToBlockNumber(byte, byte)
Determine the first block number of a specified sector and block group
public static byte SectorToBlockNumber(byte sector, byte group = 0)
Parameters
Returns
- byte
block number of the first (or only) block in the group
SetCapacity(ushort, byte)
From the ATQA ans SAK data find common card capacity
public void SetCapacity(ushort ATQA, byte SAK)
Parameters
Remarks
Does not recognize Mifare Plus cards, capacity must be set manually
TryReadNdefMessage(out NdefMessage)
Try to read a NDEF Message from a Mifare card
public bool TryReadNdefMessage(out NdefMessage message)
Parameters
message
NdefMessageThe NDEF message
Returns
- bool
True if success
WriteDataBlock(byte)
Perform a write using the 16 bytes present in Data on a specific block
public bool WriteDataBlock(byte block)
Parameters
block
byteThe block number to write
Returns
- bool
True if success
Remarks
You will need to be authenticated properly before
WriteNdefMessage(NdefMessage, bool)
Write an NDEF Message
public bool WriteNdefMessage(NdefMessage message, bool writeKeyA = true)
Parameters
message
NdefMessageThe NDEF Message to write
writeKeyA
boolTrue to write with Key A
Returns
- bool
True if success