I am using Java Smart Card API to access. I have NXP Mifare desfire 4K , 1K , Ultra light smart cards with me & trying to find out its type programically in JAVA.
<edit: Apologies that this does not directly answer the question but the current top answer is potentially harmful. I'm trying to discover how to get the SAK myself will try to post an update when I do.
Determining card type from the ATS/ATR is commonplace, but wrong. NXP advises using SAK.
"As the ATS of different MIFARE ICs can be customized, it is certainly not advisable to rely on the ATS to differentiate the IC type"
Ref: http://www.nxp.com/documents/application_note/AN10833.pdf
Instead, look here for a detailed tree of how to determine card type from the SAK: http://www.nxp.com/documents/application_note/130830.pdf
As an aside, in production if you can be assured that you will always get the same format of ATR/ATS on all your cards, that can be a viable option. But it is not guaranteed.
I have no idea what in the world VCA is, but from the first document:
"In future, NXP recommends to use “Virtual Card Architecture (VCA)” for PICC selection and type identification. If installations do not depend on the actual content of ATQA, SAK and/or ATS for card selection and identification, this allows for more than one MIFARE product being enabled for activation in a single device at the same time. In this case, the VCA allows for efficient and privacy friendly selection of the targeted MIFARE product. This is described in a separate application note."
Find out the ATR of the card and ATR contain the the information of card type. Here I am uploading image See the structure of ATR... For more info Here the full PDF look at Page no 6.
I know this is an old blog but I have been working on this same issue and wanted to share my findings.
In AN10833 it clearly states that the UID + SAK are returned from performing a select. Using the java smartcard io library I can perform a select like this:
// Send pseudo APDU to retrieve the card serial number (UID)
int cla = 0xFF;
int ins = 0xCA;
int p1 = 0x00;
int p2 = 0x00;
byte[] data = null;
int dataOffset = 0x00;
int dataLength = 0x00;
int le = 0x00;
CommandAPDU getDataApdu = new CommandAPDU(cla, ins, p1, p2, data, dataOffset, dataLength, le);
ResponseAPDU r1 = channel.transmit(getDataApdu);
However, I am only returned the UID. I found documentation on the PC/SC API that changing P1 = 0x01 will change the response to the historical bytes (which worked for me).
(section 3.2.2.1.3 from here: http://pcscworkgroup.com/Download/Specifications/pcsc3_v2.01.09.pdf)
Unfortunately, for the off-the-shelf readers I have access to I could not find the parameters to return the SAK. In a different reader's API document I found that if p2 = 0x01 the ATQA + UID + SAK is returned (this reader is propitiatory and I cannot share the doc).
I believe if your reader supports it (or you are coding at a low enough level to control the reader itself) you can get/request the exact SAK. Otherwise you may need to use the ATS/ATR to determine the card type.
Note, in Java here is the code to grab the ATS/ATR:
// wait 10 seconds for a card
CardTerminal terminal = terminal.waitForCardPresent(10000);
Card card = terminal.connect("*");
ATR atr = card.getATR();
From there, the ATR can be processed as vikky mentioned above.
I will respond with anything else I learn.