1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the common data types shared by Reader/Writer mode
22  *  and Card Emulation.
23  *
24  ******************************************************************************/
25 #include "bt_types.h"
26 #include "nfc_target.h"
27 
28 #include "nfc_api.h"
29 #include "rw_api.h"
30 #include "rw_int.h"
31 #include "tags_int.h"
32 
33 #define T1T_MAX_NUM_OPCODES 9
34 #define T1T_STATIC_OPCODES 5
35 #define T1T_MAX_TAG_MODELS 2
36 
37 const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[] = {
38     /* Note: the order of these commands can not be changed.
39      * If new events are added, add them after T1T_CMD_WRITE_NE8 */
40     /*   opcode         cmd_len,  uid_offset,  rsp_len */
41     {T1T_CMD_RID, 7, 3, 6},        {T1T_CMD_RALL, 7, 3, 122},
42     {T1T_CMD_READ, 7, 3, 2},       {T1T_CMD_WRITE_E, 7, 3, 2},
43     {T1T_CMD_WRITE_NE, 7, 3, 2},   {T1T_CMD_RSEG, 14, 10, 129},
44     {T1T_CMD_READ8, 14, 10, 9},    {T1T_CMD_WRITE_E8, 14, 10, 9},
45     {T1T_CMD_WRITE_NE8, 14, 10, 9}};
46 
47 const tT1T_INIT_TAG t1t_init_content[] = {
48     /*  Tag Name            CC3,        is dynamic, ltv[0]  ltv[1]  ltv[2]
49        mtv[0]  mtv[1]  mtv[2]*/
50     {RW_T1T_IS_TOPAZ96, 0x0E, FALSE, {0, 0, 0}, {0, 0, 0}},
51     {RW_T1T_IS_TOPAZ512, 0x3F, TRUE, {0xF2, 0x30, 0x33}, {0xF0, 0x02, 0x03}}};
52 
53 #define T2T_MAX_NUM_OPCODES 3
54 #define T2T_MAX_TAG_MODELS 7
55 
56 const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[] = {
57     /* Note: the order of these commands can not be changed.
58      * If new events are added, add them after T2T_CMD_SEC_SEL */
59     /*  opcode            cmd_len,   rsp_len, nack_rsp_len */
60     {T2T_CMD_READ, 2, 16, 1},
61     {T2T_CMD_WRITE, 6, 1, 1},
62     {T2T_CMD_SEC_SEL, 2, 1, 1}};
63 
64 const tT2T_INIT_TAG t2t_init_content[] = {
65     /*  Tag Name        is_multi_v  Ver Block                   Ver No
66        Vbitmask   to_calc_cc CC3      OTP     BLPB */
67     {TAG_MIFARE_MID, true, T2T_MIFARE_VERSION_BLOCK,
68      T2T_MIFARE_ULTRALIGHT_VER_NO, 0xFFFF, false, 0x06, false,
69      T2T_DEFAULT_LOCK_BLPB},
70     {TAG_MIFARE_MID, true, T2T_MIFARE_VERSION_BLOCK,
71      T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO, 0xFFFF, true, 0x00, false,
72      T2T_DEFAULT_LOCK_BLPB},
73     {TAG_KOVIO_MID, false, 0x00, 0x00, 0x0000, false, 0x1D, true, 0x04},
74     {TAG_INFINEON_MID, true, T2T_INFINEON_VERSION_BLOCK,
75      T2T_INFINEON_MYD_MOVE_LEAN, 0xFFF0, false, 0x06, false,
76      T2T_DEFAULT_LOCK_BLPB},
77     {TAG_INFINEON_MID, true, T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE,
78      0xFFF0, false, 0x10, false, T2T_DEFAULT_LOCK_BLPB},
79     {TAG_BRCM_MID, true, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_STATIC_MEM, 0xFFFF,
80      false, 0x06, false, T2T_DEFAULT_LOCK_BLPB},
81     {TAG_BRCM_MID, true, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_DYNAMIC_MEM, 0xFFFF,
82      false, 0x3C, false, T2T_DEFAULT_LOCK_BLPB}
83 
84 };
85 
86 const uint8_t t4t_v10_ndef_tag_aid[T4T_V10_NDEF_TAG_AID_LEN] = {
87     0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
88 const uint8_t t4t_v20_ndef_tag_aid[T4T_V20_NDEF_TAG_AID_LEN] = {
89     0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
90 
91 #if (BT_TRACE_PROTOCOL == TRUE)
92 const char* const t1t_cmd_str[] = {
93     "T1T_RID",  "T1T_RALL",  "T1T_READ",     "T1T_WRITE_E",  "T1T_WRITE_NE",
94     "T1T_RSEG", "T1T_READ8", "T1T_WRITE_E8", "T1T_WRITE_NE8"};
95 
96 const char* const t2t_cmd_str[] = {"T2T_CMD_READ", "T2T_CMD_WRITE",
97                                    "T2T_CMD_SEC_SEL"};
98 #endif
99 
100 static unsigned int tags_ones32(register unsigned int x);
101 
102 /*******************************************************************************
103 **
104 ** Function         t1t_cmd_to_rsp_info
105 **
106 ** Description      This function maps the given opcode to tT1T_CMD_RSP_INFO.
107 **
108 ** Returns          tNFC_STATUS
109 **
110 *******************************************************************************/
t1t_cmd_to_rsp_info(uint8_t opcode)111 const tT1T_CMD_RSP_INFO* t1t_cmd_to_rsp_info(uint8_t opcode) {
112   const tT1T_CMD_RSP_INFO *p_ret = NULL, *p;
113   int xx;
114 
115   for (xx = 0, p = &t1t_cmd_rsp_infos[0]; xx < T1T_MAX_NUM_OPCODES; xx++, p++) {
116     if (opcode == p->opcode) {
117       if ((xx < T1T_STATIC_OPCODES) || (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0))
118         p_ret = p;
119       break;
120     }
121   }
122 
123   return p_ret;
124 }
125 
126 /*******************************************************************************
127 **
128 ** Function         t1t_tag_init_data
129 **
130 ** Description      This function maps the given opcode to tT1T_INIT_TAG.
131 **
132 ** Returns          tNFC_STATUS
133 **
134 *******************************************************************************/
t1t_tag_init_data(uint8_t tag_model)135 const tT1T_INIT_TAG* t1t_tag_init_data(uint8_t tag_model) {
136   const tT1T_INIT_TAG *p_ret = NULL, *p;
137   int xx;
138 
139   for (xx = 0, p = &t1t_init_content[0]; xx < T1T_MAX_TAG_MODELS; xx++, p++) {
140     if (tag_model == p->tag_model) {
141       p_ret = p;
142       break;
143     }
144   }
145 
146   return p_ret;
147 }
148 
149 /*******************************************************************************
150 **
151 ** Function         t2t_tag_init_data
152 **
153 ** Description      This function maps the given manufacturer id and version to
154 **                  tT2T_INIT_TAG.
155 **
156 ** Returns          tNFC_STATUS
157 **
158 *******************************************************************************/
t2t_tag_init_data(uint8_t manufacturer_id,bool b_valid_ver,uint16_t version_no)159 const tT2T_INIT_TAG* t2t_tag_init_data(uint8_t manufacturer_id,
160                                        bool b_valid_ver, uint16_t version_no) {
161   const tT2T_INIT_TAG *p_ret = NULL, *p;
162   int xx;
163 
164   for (xx = 0, p = &t2t_init_content[0]; xx < T2T_MAX_TAG_MODELS; xx++, p++) {
165     if (manufacturer_id == p->manufacturer_id) {
166       if ((!p->b_multi_version) || (!b_valid_ver) ||
167           (p->version_no == (version_no & p->version_bmask))) {
168         p_ret = p;
169         break;
170       }
171     }
172   }
173 
174   return p_ret;
175 }
176 
177 /*******************************************************************************
178 **
179 ** Function         t2t_cmd_to_rsp_info
180 **
181 ** Description      This function maps the given opcode to tT2T_CMD_RSP_INFO.
182 **
183 ** Returns          tNFC_STATUS
184 **
185 *******************************************************************************/
t2t_cmd_to_rsp_info(uint8_t opcode)186 const tT2T_CMD_RSP_INFO* t2t_cmd_to_rsp_info(uint8_t opcode) {
187   const tT2T_CMD_RSP_INFO *p_ret = NULL, *p;
188   int xx;
189 
190   for (xx = 0, p = &t2t_cmd_rsp_infos[0]; xx < T2T_MAX_NUM_OPCODES; xx++, p++) {
191     if (opcode == p->opcode) {
192       p_ret = p;
193       break;
194     }
195   }
196 
197   return p_ret;
198 }
199 
200 /*******************************************************************************
201 **
202 ** Function         t1t_info_to_evt
203 **
204 ** Description      This function maps the given tT1T_CMD_RSP_INFO to RW/CE
205 **                  event code
206 **
207 ** Returns          RW/CE event code
208 **
209 *******************************************************************************/
t1t_info_to_evt(const tT1T_CMD_RSP_INFO * p_info)210 uint8_t t1t_info_to_evt(const tT1T_CMD_RSP_INFO* p_info) {
211   return ((uint8_t)(p_info - t1t_cmd_rsp_infos) + RW_T1T_FIRST_EVT);
212 }
213 
214 /*******************************************************************************
215 **
216 ** Function         t2t_info_to_evt
217 **
218 ** Description      This function maps the given tT2T_CMD_RSP_INFO to RW/CE
219 **                  event code
220 **
221 ** Returns          RW/CE event code
222 **
223 *******************************************************************************/
t2t_info_to_evt(const tT2T_CMD_RSP_INFO * p_info)224 uint8_t t2t_info_to_evt(const tT2T_CMD_RSP_INFO* p_info) {
225   return ((uint8_t)(p_info - t2t_cmd_rsp_infos) + RW_T2T_FIRST_EVT);
226 }
227 
228 #if (BT_TRACE_PROTOCOL == TRUE)
229 /*******************************************************************************
230 **
231 ** Function         t1t_info_to_str
232 **
233 ** Description      This function maps the given tT1T_CMD_RSP_INFO to T1T cmd
234 **                  str
235 **
236 ** Returns          T1T cmd str
237 **
238 *******************************************************************************/
t1t_info_to_str(const tT1T_CMD_RSP_INFO * p_info)239 const char* t1t_info_to_str(const tT1T_CMD_RSP_INFO* p_info) {
240   int ind = (int)(p_info - t1t_cmd_rsp_infos);
241   if (ind < T1T_MAX_NUM_OPCODES)
242     return (const char*)t1t_cmd_str[ind];
243   else
244     return "";
245 }
246 
247 /*******************************************************************************
248 **
249 ** Function         t2t_info_to_str
250 **
251 ** Description      This function maps the given tT2T_CMD_RSP_INFO to T2T cmd
252 **                  str
253 **
254 ** Returns          T2T cmd str
255 **
256 *******************************************************************************/
t2t_info_to_str(const tT2T_CMD_RSP_INFO * p_info)257 const char* t2t_info_to_str(const tT2T_CMD_RSP_INFO* p_info) {
258   int ind = (int)(p_info - t2t_cmd_rsp_infos);
259   if (ind < T2T_MAX_NUM_OPCODES)
260     return (const char*)t2t_cmd_str[ind];
261   else
262     return "";
263 }
264 #endif
265 
266 /*******************************************************************************
267 **
268 ** Function         tags_pow
269 **
270 ** Description      This function calculates x(base) power of y.
271 **
272 ** Returns          int
273 **
274 *******************************************************************************/
tags_pow(int x,int y)275 int tags_pow(int x, int y) {
276   int i, ret = 1;
277   for (i = 0; i < y; i++) {
278     ret *= x;
279   }
280   return ret;
281 }
282 
283 /*******************************************************************************
284 **
285 ** Function         ones32
286 **
287 ** Description      This function returns number of bits set in an unsigned
288 **                  integer variable
289 **
290 ** Returns          int
291 **
292 *******************************************************************************/
tags_ones32(register unsigned int x)293 static unsigned int tags_ones32(register unsigned int x) {
294   /* 32-bit recursive reduction using SWAR...
295      but first step is mapping 2-bit values
296      into sum of 2 1-bit values in sneaky way
297   */
298   x -= ((x >> 1) & 0x55555555);
299   x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
300   x = (((x >> 4) + x) & 0x0f0f0f0f);
301   x += (x >> 8);
302   x += (x >> 16);
303   return (x & 0x0000003f);
304 }
305 
306 /*******************************************************************************
307 **
308 ** Function         tags_log2
309 **
310 ** Description      This function calculates log to the base  2.
311 **
312 ** Returns          int
313 **
314 *******************************************************************************/
tags_log2(register unsigned int x)315 unsigned int tags_log2(register unsigned int x) {
316   x |= (x >> 1);
317   x |= (x >> 2);
318   x |= (x >> 4);
319   x |= (x >> 8);
320   x |= (x >> 16);
321 
322   return (tags_ones32(x) - 1);
323 }
324