11 #include "../Common.h" 14 #define ISO14443A_UID_SIZE_SINGLE 4 15 #define ISO14443A_UID_SIZE_DOUBLE 7 16 #define ISO14443A_UID_SIZE_TRIPLE 10 18 #define ISO14443A_CMD_REQA 0x26 19 #define ISO14443A_CMD_WUPA 0x52 20 #define ISO14443A_CMD_SELECT_CL1 0x93 21 #define ISO14443A_CMD_SELECT_CL2 0x95 22 #define ISO14443A_CMD_SELECT_CL3 0x97 23 #define ISO14443A_CMD_HLTA 0x50 25 #define ISO14443A_NVB_AC_START 0x20 26 #define ISO14443A_NVB_AC_END 0x70 28 #define IsSelectCmd(Buffer) ((Buffer[0] == ISO14443A_CMD_SELECT_CL1) || \ 29 (Buffer[0] == ISO14443A_CMD_SELECT_CL2) || \ 30 (Buffer[0] == ISO14443A_CMD_SELECT_CL3)) 31 #define IsCmdSelectRound1(Buffer) (IsSelectCmd(Buffer) && (Buffer[1] == ISO14443A_NVB_AC_START)) 32 #define IsCmdSelectRound2(Buffer) (IsSelectCmd(Buffer) && (Buffer[1] == ISO14443A_NVB_AC_END)) 34 #define ISO14443A_CL_UID_OFFSET 0 35 #define ISO14443A_CL_UID_SIZE 4 36 #define ISO14443A_CL_BCC_OFFSET 4 37 #define ISO14443A_CL_BCC_SIZE 1 38 #define ISO14443A_CL_FRAME_SIZE ((ISO14443A_CL_UID_SIZE + ISO14443A_CL_BCC_SIZE) * 8) 39 #define ISO14443A_SAK_INCOMPLETE 0x24 // 0x04 40 #define ISO14443A_SAK_COMPLETE_COMPLIANT 0x20 41 #define ISO14443A_SAK_COMPLETE_NOT_COMPLIANT 0x00 43 #define ISO14443A_ATQA_FRAME_SIZE_BYTES (2) 44 #define ISO14443A_ATQA_FRAME_SIZE (2 * BITS_PER_BYTE) 45 #define ISO14443A_SAK_FRAME_SIZE (3 * BITS_PER_BYTE) 46 #define ISO14443A_HLTA_FRAME_SIZE (2 * BITS_PER_BYTE) 48 #define ISO14443A_UID0_RANDOM 0x08 49 #define ISO14443A_UID0_CT 0x88 51 #define ISO14443A_CRCA_SIZE 2 53 #define ISO14443A_CALC_BCC(ByteBuffer) \ 54 ( ByteBuffer[0] ^ ByteBuffer[1] ^ ByteBuffer[2] ^ ByteBuffer[3] ) 56 void ISO14443AAppendCRCA(
void *Buffer, uint16_t ByteCount);
57 bool ISO14443ACheckCRCA(
const void *Buffer, uint16_t ByteCount);
59 INLINE
bool ISO14443ASelect(
void *Buffer, uint16_t *BitCount, uint8_t *UidCL, uint8_t SAKValue);
60 INLINE
bool ISO14443AWakeUp(
void *Buffer, uint16_t *BitCount, uint16_t ATQAValue,
bool FromHalt);
63 bool ISO14443ASelect(
void *Buffer, uint16_t *BitCount, uint8_t *UidCL, uint8_t SAKValue) {
64 uint8_t *DataPtr = (uint8_t *) Buffer;
65 uint8_t NVB = DataPtr[1];
68 case ISO14443A_NVB_AC_START:
71 DataPtr[0] = UidCL[0];
72 DataPtr[1] = UidCL[1];
73 DataPtr[2] = UidCL[2];
74 DataPtr[3] = UidCL[3];
75 DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
76 *BitCount = ISO14443A_CL_FRAME_SIZE;
79 case ISO14443A_NVB_AC_END:
82 if ((DataPtr[2] == UidCL[0]) &&
83 (DataPtr[3] == UidCL[1]) &&
84 (DataPtr[4] == UidCL[2]) &&
85 (DataPtr[5] == UidCL[3])) {
86 DataPtr[0] = SAKValue;
87 ISO14443AAppendCRCA(Buffer, 1);
88 *BitCount = ISO14443A_SAK_FRAME_SIZE;
96 uint8_t CollisionByteCount = ((NVB >> 4) & 0x0f) - 2;
97 uint8_t CollisionBitCount = (NVB >> 0) & 0x0f;
98 uint8_t mask = 0xFF >> (8 - CollisionBitCount);
101 ((CollisionByteCount == 5 || (CollisionByteCount == 4 && CollisionBitCount > 0)) && memcmp(UidCL, &DataPtr[2], 4) == 0 && (ISO14443A_CALC_BCC(UidCL) & mask) == (DataPtr[6] & mask))
103 (CollisionByteCount == 4 && CollisionBitCount == 0 && memcmp(UidCL, &DataPtr[2], 4) == 0)
105 (CollisionByteCount < 4 && memcmp(UidCL, &DataPtr[2], CollisionByteCount) == 0 && (UidCL[CollisionByteCount] & mask) == (DataPtr[CollisionByteCount + 2] & mask))
107 DataPtr[0] = UidCL[0];
108 DataPtr[1] = UidCL[1];
109 DataPtr[2] = UidCL[2];
110 DataPtr[3] = UidCL[3];
111 DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
113 *BitCount = ISO14443A_CL_FRAME_SIZE;
125 #ifdef CONFIG_MF_DESFIRE_SUPPORT 126 bool ISO14443ASelectDesfire(
void *Buffer, uint16_t *BitCount, uint8_t *UidCL, uint8_t SAKValue);
130 bool ISO14443AWakeUp(
void *Buffer, uint16_t *BitCount, uint16_t ATQAValue,
bool FromHalt) {
131 uint8_t *DataPtr = (uint8_t *) Buffer;
133 if (((! FromHalt) && (DataPtr[0] == ISO14443A_CMD_REQA)) ||
134 (DataPtr[0] == ISO14443A_CMD_WUPA)) {
135 DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
136 DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
138 *BitCount = ISO14443A_ATQA_FRAME_SIZE;