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