Chameleon-Mini
 All Classes Files Functions Variables Macros Pages
ISO14443-3A.h
1 /* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL
2  * AUTHORS"). All rights reserved.
3  *
4  * DEFINITIONS:
5  *
6  * "WORK": The material covered by this license includes the schematic
7  * diagrams, designs, circuit or circuit board layouts, mechanical
8  * drawings, documentation (in electronic or printed form), source code,
9  * binary software, data files, assembled devices, and any additional
10  * material provided by the ORIGINAL AUTHORS in the ChameleonMini project
11  * (https://github.com/skuep/ChameleonMini).
12  *
13  * LICENSE TERMS:
14  *
15  * Redistributions and use of this WORK, with or without modification, or
16  * of substantial portions of this WORK are permitted provided that the
17  * following conditions are met:
18  *
19  * Redistributions and use of this WORK, with or without modification, or
20  * of substantial portions of this WORK must include the above copyright
21  * notice, this list of conditions, the below disclaimer, and the following
22  * attribution:
23  *
24  * "Based on ChameleonMini an open-source RFID emulator:
25  * https://github.com/skuep/ChameleonMini"
26  *
27  * The attribution must be clearly visible to a user, for example, by being
28  * printed on the circuit board and an enclosure, and by being displayed by
29  * software (both in binary and source code form).
30  *
31  * At any time, the majority of the ORIGINAL AUTHORS may decide to give
32  * written permission to an entity to use or redistribute the WORK (with or
33  * without modification) WITHOUT having to include the above copyright
34  * notice, this list of conditions, the below disclaimer, and the above
35  * attribution.
36  *
37  * DISCLAIMER:
38  *
39  * THIS PRODUCT IS PROVIDED BY THE ORIGINAL AUTHORS "AS IS" AND ANY EXPRESS
40  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE ORIGINAL AUTHORS OR CONTRIBUTORS BE
43  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
44  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
45  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
46  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS PRODUCT, EVEN IF ADVISED OF
49  * THE POSSIBILITY OF SUCH DAMAGE.
50  *
51  * The views and conclusions contained in the hardware, software, and
52  * documentation should not be interpreted as representing official
53  * policies, either expressed or implied, of the ORIGINAL AUTHORS.
54  */
55 
56 #ifndef ISO14443_3A_H_
57 #define ISO14443_3A_H_
58 
59 #include "../Common.h"
60 
61 #define ISO14443A_UID_SIZE_SINGLE 4 /* bytes */
62 #define ISO14443A_UID_SIZE_DOUBLE 7
63 #define ISO14443A_UID_SIZE_TRIPLE 10
64 
65 #define ISO14443A_CMD_REQA 0x26
66 #define ISO14443A_CMD_WUPA 0x52
67 #define ISO14443A_CMD_SELECT_CL1 0x93
68 #define ISO14443A_CMD_SELECT_CL2 0x95
69 #define ISO14443A_CMD_SELECT_CL3 0x97
70 #define ISO14443A_CMD_HLTA 0x50
71 
72 #define ISO14443A_NVB_AC_START 0x20
73 #define ISO14443A_NVB_AC_END 0x70
74 
75 #define ISO14443A_CL_UID_OFFSET 0
76 #define ISO14443A_CL_UID_SIZE 4
77 #define ISO14443A_CL_BCC_OFFSET 4
78 #define ISO14443A_CL_BCC_SIZE 1 /* Byte */
79 #define ISO14443A_CL_FRAME_SIZE ((ISO14443A_CL_UID_SIZE + ISO14443A_CL_BCC_SIZE) * 8) /* UID[N...N+3] || BCCN */
80 #define ISO14443A_SAK_INCOMPLETE 0x04
81 #define ISO14443A_SAK_COMPLETE_COMPLIANT 0x20
82 #define ISO14443A_SAK_COMPLETE_NOT_COMPLIANT 0x00
83 
84 #define ISO14443A_ATQA_FRAME_SIZE (2 * 8) /* Bit */
85 #define ISO14443A_SAK_FRAME_SIZE (3 * 8) /* Bit */
86 
87 #define ISO14443A_UID0_RANDOM 0x08
88 #define ISO14443A_UID0_CT 0x88
89 
90 #define ISO14443A_CRCA_SIZE 2
91 
92 #define ISO14443A_CALC_BCC(ByteBuffer) \
93  ( ByteBuffer[0] ^ ByteBuffer[1] ^ ByteBuffer[2] ^ ByteBuffer[3] )
94 
95 void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount);
96 bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount);
97 
98 INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue);
99 INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue);
100 
101 INLINE
102 bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
103 {
104  uint8_t* DataPtr = (uint8_t*) Buffer;
105  uint8_t NVB = DataPtr[1];
106  //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
107  //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
108 
109  switch (NVB) {
110  case ISO14443A_NVB_AC_START:
111  /* Start of anticollision procedure.
112  * Send whole UID CLn + BCC */
113  DataPtr[0] = UidCL[0];
114  DataPtr[1] = UidCL[1];
115  DataPtr[2] = UidCL[2];
116  DataPtr[3] = UidCL[3];
117  DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
118 
119  *BitCount = ISO14443A_CL_FRAME_SIZE;
120 
121  return false;
122 
123  case ISO14443A_NVB_AC_END:
124  /* End of anticollision procedure.
125  * Send SAK CLn if we are selected. */
126  if ( (DataPtr[2] == UidCL[0]) &&
127  (DataPtr[3] == UidCL[1]) &&
128  (DataPtr[4] == UidCL[2]) &&
129  (DataPtr[5] == UidCL[3]) ) {
130 
131  DataPtr[0] = SAKValue;
132  ISO14443AAppendCRCA(Buffer, 1);
133 
134  *BitCount = ISO14443A_SAK_FRAME_SIZE;
135  return true;
136  } else {
137  /* We have not been selected. Don't send anything. */
138  *BitCount = 0;
139  return false;
140  }
141  default:
142  /* TODO: No anticollision supported */
143  *BitCount = 0;
144  return false;
145  }
146 }
147 
148 INLINE
149 bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue)
150 {
151  uint8_t* DataPtr = (uint8_t*) Buffer;
152 
153  if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){
154  DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
155  DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
156 
157  *BitCount = ISO14443A_ATQA_FRAME_SIZE;
158 
159  return true;
160  } else {
161  return false;
162  }
163 }
164 
165 #endif