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
37const 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
47const 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
56const 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
64const 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
86const uint8_t t4t_v10_ndef_tag_aid[T4T_V10_NDEF_TAG_AID_LEN] = {
87    0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
88const 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)
92const 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
96const char* const t2t_cmd_str[] = {"T2T_CMD_READ", "T2T_CMD_WRITE",
97                                   "T2T_CMD_SEC_SEL"};
98#endif
99
100static 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*******************************************************************************/
111const 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*******************************************************************************/
135const 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*******************************************************************************/
159const 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*******************************************************************************/
186const 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*******************************************************************************/
210uint8_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*******************************************************************************/
224uint8_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*******************************************************************************/
239const 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*******************************************************************************/
257const 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*******************************************************************************/
275int 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*******************************************************************************/
293static 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*******************************************************************************/
315unsigned 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