Post by PugI need the ATS when using Mifare cards as they respond with their serial
number in the ATS, on some applications its used to calculate the secret
keys. In the technical manual of the scr331-di manual it states that sending
the picc escape command with a function called 'Reader_cntless_get_ats' it
should return the ATS of the contactless you just connected to,
i.e. ret = scardcontrol(cardhandle, IOCTL_CCID_ESCAPE,
Reader_Cntless_Get_Ats, 1, outbuf, outbuflength, reslen)
ok, I got your point.
there is not GET ATS escape message, OOH the PUID (or UID or PUPI) is
not returned into the ATS with default settings.
to obtain this information, you must first enable the Get PUPI feature,
then request the ATS and extract the UID from it, ie:
SCARDHANDLE scard; // is assumed to contain a valid handle
#define IOCTL_CCID_ESCAPE SCARD_CTL_CODE(0xDAC)
// the 3 escape commands are
#define CCID_GET_PUPI_STATUS 0xFF9B
#define CCID_SET_PUPI_ON 0x019B
#define CCID_SET_PUPI_OFF 0x009B
// enable the "get UID" feature
WORD command = CCID_SET_PUPI_ON;
byte outByte;
ULONG length = 1;
long err = ::SCardControl(scard, IOCTL_CCID_ESCAPE,
&command, 2, &outByte, 1, &length);
// now request the ATS
byte ats[32];
length = 32;
err = ::SCardGetAttrib(scard, SCARD_ATTR_ATR_STRING, ats, &length);
// the ATS shall read:
// ats[ 0] = 0x3B Proprietary
// ats[ 1] = 0xFn n indicates the number of bytes following
// atr[ 2] = 0x91 Proprietary
// atr[ 3] = 0x00 Proprietary
// atr[ 4] = 0xFF Proprietary
// atr[ 5] = 0x91 Proprietary
// atr[ 6] = 0x81 Proprietary
// atr[ 7] = 0x71 Proprietary
// atr[ 8] = 0xFE Proprietary
// atr[ 9] = 0x40 Proprietary
// atr[10] = 0x00 Proprietary
// atr[11] = 'A' or 'B'
// atr[12] = SAK Selective Acknowledgement for Type A ONLY
// atr[13] = UID length (shall be 4, 7 or 10)
// atr[14] = first (MSB) byte of UID
// atr[15] = second byte of UID
// atr[..] = first (MSB) byte of UID
// atr[nn] = last (LSB) byte of UID
// atr[+1] = 0xY1 (Y = SFGI value)
// atr[+2] = baud rate
// atr[+3] = wait time integer
// atr[+4] = first historical byte for type A only
// atr[+5] = next historical byte
// atr[++] = next historical byte, and so on
// atr[+n] = TCK
so using a type A card, your data start at (ats + 14) and are ats[13]
bytes long.
Sylvain.