blob: caeb22bbb934ad6a50498ebc52ac3ffd8519b627 [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chue9629ba2014-01-31 11:18:47 -05003 * Copyright (C) 2011-2014 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
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 implementation for ISO 15693 in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
Jack Yu790603c2019-01-28 20:29:31 +080025#include <log/log.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080026#include <string.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080027
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080028#include <android-base/stringprintf.h>
29#include <base/logging.h>
30
31#include "nfc_target.h"
32
33#include "bt_types.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080034#include "nfc_api.h"
35#include "nfc_int.h"
36#include "rw_api.h"
37#include "rw_int.h"
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080038
39using android::base::StringPrintf;
40
41extern bool nfc_debug_enabled;
Arach MOHAMMED BRAHIMe05a0972020-10-09 17:06:56 +020042extern unsigned char appl_dta_mode_flag;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080043
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080044/* Response timeout */
45#define RW_I93_TOUT_RESP 1000
46/* stay quiet timeout */
47#define RW_I93_TOUT_STAY_QUIET 200
48/* max reading data if read multi block is supported */
49#define RW_I93_READ_MULTI_BLOCK_SIZE 128
50/* CC, zero length NDEF, Terminator TLV */
51#define RW_I93_FORMAT_DATA_LEN 8
52/* max getting lock status if get multi block sec is supported */
53#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080054
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070055static std::string rw_i93_get_tag_name(uint8_t product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080056
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080057static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
58 tNFC_CONN* p_data);
59void rw_i93_handle_error(tNFC_STATUS status);
60tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
Raphael Collado867d5c32017-03-27 12:49:40 +020061tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080062
63/*******************************************************************************
64**
65** Function rw_i93_get_product_version
66**
67** Description Get product version from UID
68**
69** Returns void
70**
71*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080072void rw_i93_get_product_version(uint8_t* p_uid) {
73 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080074
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080075 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
76 return;
77 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080078
Ruchi Kandoi6767aec2017-09-26 09:46:26 -070079 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080080
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080081 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080082
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080083 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
84 if (p_uid[2] == I93_UID_ICODE_SLI)
85 p_i93->product_version = RW_I93_ICODE_SLI;
86 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
87 p_i93->product_version = RW_I93_ICODE_SLI_S;
88 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
89 p_i93->product_version = RW_I93_ICODE_SLI_L;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080090 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080091 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
92 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
93 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
94 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
95 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
96 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
97 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
98 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
99 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
100 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
101 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
102 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
103 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
104 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
105 else
106 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
107 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
108 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
109 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
110 p_i93->product_version = RW_I93_STM_M24LR04E_R;
111 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
112 p_i93->product_version = RW_I93_STM_M24LR16E_R;
Olivier Lorente487e6d12021-04-27 16:13:23 +0200113 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16D_W)
114 p_i93->product_version = RW_I93_STM_M24LR16D_W;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800115 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
116 p_i93->product_version = RW_I93_STM_M24LR64E_R;
Raphael Collado867d5c32017-03-27 12:49:40 +0200117 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DVHIK)
118 p_i93->product_version = RW_I93_STM_ST25DVHIK;
119 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DV04K)
120 p_i93->product_version = RW_I93_STM_ST25DV04K;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800121 else {
122 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
123 case I93_IC_REF_STM_LRI1K:
124 p_i93->product_version = RW_I93_STM_LRI1K;
125 break;
126 case I93_IC_REF_STM_LRI2K:
127 p_i93->product_version = RW_I93_STM_LRI2K;
128 break;
129 case I93_IC_REF_STM_LRIS2K:
130 p_i93->product_version = RW_I93_STM_LRIS2K;
131 break;
132 case I93_IC_REF_STM_LRIS64K:
133 p_i93->product_version = RW_I93_STM_LRIS64K;
134 break;
135 case I93_IC_REF_STM_M24LR64_R:
136 p_i93->product_version = RW_I93_STM_M24LR64_R;
137 break;
138 default:
139 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
140 break;
141 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800142 }
Adrian Mocanu476558f2020-02-05 09:37:41 +0000143 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_ONS) &&
144 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
145 switch (p_i93->ic_reference) {
146 case I93_IC_REF_ONS_N36RW02:
147 p_i93->product_version = RW_I93_ONS_N36RW02;
148 break;
149 case I93_IC_REF_ONS_N24RF04:
150 p_i93->product_version = RW_I93_ONS_N24RF04;
151 break;
152 case I93_IC_REF_ONS_N24RF04E:
153 p_i93->product_version = RW_I93_ONS_N24RF04E;
154 break;
George Chang91688f62020-04-16 11:34:18 +0800155 case I93_IC_REF_ONS_N24RF16:
Adrian Mocanu476558f2020-02-05 09:37:41 +0000156 p_i93->product_version = RW_I93_ONS_N24RF16;
157 break;
George Chang91688f62020-04-16 11:34:18 +0800158 case I93_IC_REF_ONS_N24RF16E:
Adrian Mocanu476558f2020-02-05 09:37:41 +0000159 p_i93->product_version = RW_I93_ONS_N24RF16E;
160 break;
George Chang91688f62020-04-16 11:34:18 +0800161 case I93_IC_REF_ONS_N24RF64:
Adrian Mocanu476558f2020-02-05 09:37:41 +0000162 p_i93->product_version = RW_I93_ONS_N24RF64;
163 break;
George Chang91688f62020-04-16 11:34:18 +0800164 case I93_IC_REF_ONS_N24RF64E:
Adrian Mocanu476558f2020-02-05 09:37:41 +0000165 p_i93->product_version = RW_I93_ONS_N24RF64E;
166 break;
167 default:
168 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
169 break;
170 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800171 } else {
172 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
173 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800174
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700175 DLOG_IF(INFO, nfc_debug_enabled)
176 << StringPrintf("product_version = <%s>",
177 rw_i93_get_tag_name(p_i93->product_version).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800179 switch (p_i93->product_version) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800180 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
181 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800182 /* these don't support Get System Information Command */
183 /* these support only Inventory, Stay Quiet, Read Single Block, Write
184 * Single Block, Lock Block */
185 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
186 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
187 break;
Evan Chu85b7e842013-01-18 11:02:50 -0500188 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800189 break;
190 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800191}
192
193/*******************************************************************************
194**
Raphael Collado867d5c32017-03-27 12:49:40 +0200195** Function rw_i93_process_ext_sys_info
196**
197** Description Store extended system information of tag
198**
199** Returns FALSE if retrying with protocol extension flag
200**
201*******************************************************************************/
Jack Yu790603c2019-01-28 20:29:31 +0800202bool rw_i93_process_ext_sys_info(uint8_t* p_data, uint16_t length) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200203 uint8_t* p = p_data;
204 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
205 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
206
207 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
208
Jack Yu790603c2019-01-28 20:29:31 +0800209 if (length < (I93_UID_BYTE_LEN + 1)) {
210 android_errorWriteLog(0x534e4554, "122316913");
211 return false;
212 }
213
Raphael Collado867d5c32017-03-27 12:49:40 +0200214 STREAM_TO_UINT8(p_i93->info_flags, p);
Jack Yu790603c2019-01-28 20:29:31 +0800215 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200216
217 p_uid = uid;
218 STREAM_TO_ARRAY8(p_uid, p);
Jack Yu790603c2019-01-28 20:29:31 +0800219 length -= I93_UID_BYTE_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200220
221 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Jack Yu790603c2019-01-28 20:29:31 +0800222 if (length < I93_INFO_DSFID_LEN) {
223 android_errorWriteLog(0x534e4554, "122316913");
224 return false;
225 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200226 STREAM_TO_UINT8(p_i93->dsfid, p);
Jack Yu790603c2019-01-28 20:29:31 +0800227 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200228 }
229 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Jack Yu790603c2019-01-28 20:29:31 +0800230 if (length < I93_INFO_AFI_LEN) {
231 android_errorWriteLog(0x534e4554, "122316913");
232 return false;
233 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200234 STREAM_TO_UINT8(p_i93->afi, p);
Jack Yu790603c2019-01-28 20:29:31 +0800235 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200236 }
237 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Jack Yu790603c2019-01-28 20:29:31 +0800238 if (length < I93_INFO_16BIT_NUM_BLOCK_LEN + I93_INFO_BLOCK_SIZE_LEN) {
239 android_errorWriteLog(0x534e4554, "122316913");
240 return false;
241 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200242 STREAM_TO_UINT16(p_i93->num_block, p);
Jack Yu790603c2019-01-28 20:29:31 +0800243 length -= I93_INFO_16BIT_NUM_BLOCK_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200244
245 /* it is one less than actual number of bytes */
246 p_i93->num_block += 1;
247
248 STREAM_TO_UINT8(p_i93->block_size, p);
Jack Yu790603c2019-01-28 20:29:31 +0800249 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200250 /* it is one less than actual number of blocks */
251 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
252 }
253 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Jack Yu790603c2019-01-28 20:29:31 +0800254 if (length < I93_INFO_IC_REF_LEN) {
255 android_errorWriteLog(0x534e4554, "122316913");
256 return false;
257 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200258 STREAM_TO_UINT8(p_i93->ic_reference, p);
Jack Yu790603c2019-01-28 20:29:31 +0800259 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200260
261 /* clear existing UID to set product version */
262 p_i93->uid[0] = 0x00;
263
264 /* store UID and get product version */
265 rw_i93_get_product_version(p_uid);
266
267 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
Adrian Mocanu476558f2020-02-05 09:37:41 +0000268 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)){
269 /* STM & ONS supports more than 2040 bytes */
Raphael Collado867d5c32017-03-27 12:49:40 +0200270 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
271 }
272 }
273 }
274 return true;
275}
276
277/*******************************************************************************
278**
Evan Chu85b7e842013-01-18 11:02:50 -0500279** Function rw_i93_process_sys_info
280**
281** Description Store system information of tag
282**
283** Returns FALSE if retrying with protocol extension flag
284**
285*******************************************************************************/
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800286bool rw_i93_process_sys_info(uint8_t* p_data, uint16_t length) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800287 uint8_t* p = p_data;
288 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
289 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -0500290
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700291 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500292
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800293 if (length < (I93_UID_BYTE_LEN + 1)) {
294 android_errorWriteLog(0x534e4554, "121259048");
295 return false;
296 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800297 STREAM_TO_UINT8(p_i93->info_flags, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800298 length--;
Evan Chu85b7e842013-01-18 11:02:50 -0500299
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800300 p_uid = uid;
301 STREAM_TO_ARRAY8(p_uid, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800302 length -= I93_UID_BYTE_LEN;
Evan Chu85b7e842013-01-18 11:02:50 -0500303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800304 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800305 if (length == 0) {
306 android_errorWriteLog(0x534e4554, "121259048");
307 return false;
308 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800309 STREAM_TO_UINT8(p_i93->dsfid, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800310 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800311 }
312 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800313 if (length == 0) {
314 android_errorWriteLog(0x534e4554, "121259048");
315 return false;
316 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800317 STREAM_TO_UINT8(p_i93->afi, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800318 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800319 }
320 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800321 bool block_16_bit = p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK;
322 if (block_16_bit && length > 2) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800323 STREAM_TO_UINT16(p_i93->num_block, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800324 length -= 2;
325 } else if (!block_16_bit && length > 1) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800326 STREAM_TO_UINT8(p_i93->num_block, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800327 length--;
328 } else {
329 android_errorWriteLog(0x534e4554, "121259048");
330 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500331 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800332 /* it is one less than actual number of bytes */
333 p_i93->num_block += 1;
Evan Chu85b7e842013-01-18 11:02:50 -0500334
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800335 STREAM_TO_UINT8(p_i93->block_size, p);
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800336 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800337 /* it is one less than actual number of blocks */
338 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
339 }
340 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800341 if (length == 0) {
342 android_errorWriteLog(0x534e4554, "121259048");
343 return false;
344 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800345 STREAM_TO_UINT8(p_i93->ic_reference, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500346
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800347 /* clear existing UID to set product version */
348 p_i93->uid[0] = 0x00;
Evan Chu85b7e842013-01-18 11:02:50 -0500349
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800350 /* store UID and get product version */
351 rw_i93_get_product_version(p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -0500352
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800353 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
354 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
355 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
356 p_i93->num_block = 8;
357 p_i93->block_size = 4;
358 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
359 /*
360 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
361 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
362 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
363 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
364 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
365 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
366 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
Olivier Lorente487e6d12021-04-27 16:13:23 +0200367 ** M24LR16D-W: 01001101(b), blockSize: 4, numberBlocks: 0x200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800368 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
369 */
370 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
Olivier Lorente487e6d12021-04-27 16:13:23 +0200371 (p_i93->product_version == RW_I93_STM_M24LR16D_W) ||
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800372 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
373 /*
Olivier Lorente487e6d12021-04-27 16:13:23 +0200374 ** M24LR16E-R or M24LR16D-W or M24LR64E-R returns system information
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800375 ** without memory size, if option flag is not set.
376 ** LRIS64K and M24LR64-R return error if option flag is not
377 ** set.
378 */
379 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
380 /* get memory size with protocol extension flag */
Yi Kong805e3612018-07-25 14:07:29 -0700381 if (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_YES) ==
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800382 NFC_STATUS_OK) {
383 /* STM supports more than 2040 bytes */
384 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
385
386 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500387 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800388 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800389 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
390 (p_i93->ic_reference == 0x21)) {
391 /* workaround of byte order in memory size information */
392 p_i93->num_block = 64;
393 p_i93->block_size = 4;
Raphael Collado867d5c32017-03-27 12:49:40 +0200394 } else if (!(p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)) {
395 if (!(p_i93->intl_flags & RW_I93_FLAG_EXT_COMMANDS)) {
Yi Kong805e3612018-07-25 14:07:29 -0700396 if (rw_i93_send_cmd_get_ext_sys_info(nullptr) == NFC_STATUS_OK) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200397 /* STM supports more than 2040 bytes */
398 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
399
400 return false;
401 }
402 }
Evan Chu85b7e842013-01-18 11:02:50 -0500403 }
Adrian Mocanu476558f2020-02-05 09:37:41 +0000404 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
405 /*
406 ** N36RW02: 00011010(b), blockSize: 4, numberBlocks: 0x40
407 ** N24RF04: 00101110(b), blockSize: 4, numberBlocks: 0x80
408 ** N24RF04E: 00101010(b), blockSize: 4, numberBlocks: 0x80
409 ** N24RF16: 01001010(b), blockSize: 4, numberBlocks: 0x200
410 ** N24RF16E: 01001110(b), blockSize: 4, numberBlocks: 0x200
411 ** N24RF64: 01101010(b), blockSize: 4, numberBlocks: 0x800
412 ** N24RF64E: 01101110(b), blockSize: 4, numberBlocks: 0x800
413 */
414 p_i93->block_size = 4;
415 switch (p_i93->product_version){
416 case RW_I93_ONS_N36RW02:
417 p_i93->num_block = 0x40;
418 break;
419 case RW_I93_ONS_N24RF04:
420 case RW_I93_ONS_N24RF04E:
421 p_i93->num_block = 0x80;
422 break;
423 case RW_I93_ONS_N24RF16:
424 case RW_I93_ONS_N24RF16E:
425 p_i93->num_block = 0x200;
George Chang91688f62020-04-16 11:34:18 +0800426 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
Adrian Mocanu476558f2020-02-05 09:37:41 +0000427 break;
428 case RW_I93_ONS_N24RF64:
429 case RW_I93_ONS_N24RF64E:
430 p_i93->num_block = 0x800;
George Chang91688f62020-04-16 11:34:18 +0800431 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
Adrian Mocanu476558f2020-02-05 09:37:41 +0000432 break;
433 default:
434 return false;
435 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800436 }
Evan Chu85b7e842013-01-18 11:02:50 -0500437 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800438 }
Evan Chu85b7e842013-01-18 11:02:50 -0500439
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800440 return true;
Evan Chu85b7e842013-01-18 11:02:50 -0500441}
442
443/*******************************************************************************
444**
445** Function rw_i93_check_sys_info_prot_ext
446**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800447** Description Check if need to set protocol extension flag to get system
448** info
Evan Chu85b7e842013-01-18 11:02:50 -0500449**
450** Returns TRUE if sent Get System Info with protocol extension flag
451**
452*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800453bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
454 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -0500455
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700456 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500457
Adrian Mocanu476558f2020-02-05 09:37:41 +0000458 if (((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) || (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS)) &&
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800459 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
460 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
Yi Kong805e3612018-07-25 14:07:29 -0700461 (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_YES) ==
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800462 NFC_STATUS_OK)) {
463 return true;
464 } else {
465 return false;
466 }
Evan Chu85b7e842013-01-18 11:02:50 -0500467}
468
469/*******************************************************************************
470**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800471** Function rw_i93_send_to_upper
472**
473** Description Send response to upper layer
474**
475** Returns void
476**
477*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800478void rw_i93_send_to_upper(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700479 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800480 uint16_t length = p_resp->len;
481 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
482 tRW_DATA rw_data;
483 uint8_t event = RW_I93_MAX_EVT;
484 uint8_t flags;
485 NFC_HDR* p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800486
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700487 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800488
Jack Yu790603c2019-01-28 20:29:31 +0800489 if (length == 0) {
490 android_errorWriteLog(0x534e4554, "121035878");
491 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
492 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
493 rw_cb.tcb.i93.sent_cmd = 0;
494 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
495 return;
496 }
497
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800498 STREAM_TO_UINT8(flags, p);
499 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800500
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800501 if (flags & I93_FLAG_ERROR_DETECTED) {
502 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
503 /* getting system info with protocol extension flag */
Adrian Mocanu476558f2020-02-05 09:37:41 +0000504 /* This STM & ONS tag supports more than 2040 bytes */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800505 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
506 p_i93->state = RW_I93_STATE_BUSY;
Jack Yu790603c2019-01-28 20:29:31 +0800507 } else if (length) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800508 /* notify error to upper layer */
509 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
510 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
511 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800512
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800513 rw_cb.tcb.i93.sent_cmd = 0;
514 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800515 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800516 return;
517 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800518
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800519 switch (p_i93->sent_cmd) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800520 case I93_CMD_INVENTORY:
Jack Yu790603c2019-01-28 20:29:31 +0800521 if (length < I93_INFO_DSFID_LEN + I93_UID_BYTE_LEN) return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800522
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800523 /* forward inventory response */
524 rw_data.i93_inventory.status = NFC_STATUS_OK;
525 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800526
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800527 p_uid = rw_data.i93_inventory.uid;
528 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800529
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800530 /* store UID and get product version */
531 rw_i93_get_product_version(p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800532
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800533 event = RW_I93_INVENTORY_EVT;
534 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800535
536 case I93_CMD_READ_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200537 case I93_CMD_EXT_READ_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800538 case I93_CMD_READ_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200539 case I93_CMD_EXT_READ_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800540 case I93_CMD_GET_MULTI_BLK_SEC:
Raphael Collado867d5c32017-03-27 12:49:40 +0200541 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800542
Alisher Alikhodjaev21c4d8b2023-05-02 14:20:57 -0700543 if (UINT16_MAX - length < NFC_HDR_SIZE) {
544 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
545 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
546 rw_cb.tcb.i93.sent_cmd = 0;
547
548 event = RW_I93_CMD_CMPL_EVT;
549 break;
550 }
551
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800552 /* forward tag data or security status */
553 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800554
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800555 if (p_buff) {
556 p_buff->offset = 0;
557 p_buff->len = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800558
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800559 memcpy((p_buff + 1), p, length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800560
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800561 rw_data.i93_data.status = NFC_STATUS_OK;
562 rw_data.i93_data.command = p_i93->sent_cmd;
563 rw_data.i93_data.p_data = p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800564
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800565 event = RW_I93_DATA_EVT;
566 } else {
567 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
568 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
569 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800570
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800571 event = RW_I93_CMD_CMPL_EVT;
572 }
573 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800574
575 case I93_CMD_WRITE_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200576 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800577 case I93_CMD_LOCK_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200578 case I93_CMD_EXT_LOCK_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800579 case I93_CMD_WRITE_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200580 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800581 case I93_CMD_SELECT:
582 case I93_CMD_RESET_TO_READY:
583 case I93_CMD_WRITE_AFI:
584 case I93_CMD_LOCK_AFI:
585 case I93_CMD_WRITE_DSFID:
586 case I93_CMD_LOCK_DSFID:
587
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800588 /* notify the complete of command */
589 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
590 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
591 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800592
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800593 event = RW_I93_CMD_CMPL_EVT;
594 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800595
596 case I93_CMD_GET_SYS_INFO:
597
Ruchi Kandoi451edc92019-01-24 14:45:55 -0800598 if (rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800599 rw_data.i93_sys_info.status = NFC_STATUS_OK;
600 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
601 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
602 rw_data.i93_sys_info.afi = p_i93->afi;
603 rw_data.i93_sys_info.num_block = p_i93->num_block;
604 rw_data.i93_sys_info.block_size = p_i93->block_size;
605 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
Evan Chu85b7e842013-01-18 11:02:50 -0500606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800607 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
Evan Chu85b7e842013-01-18 11:02:50 -0500608
George Changff05f952021-03-15 05:51:51 +0000609 p_i93->i93_t5t_mode = RW_I93_GET_SYS_INFO_MEM_INFO;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800610 event = RW_I93_SYS_INFO_EVT;
611 } else {
612 /* retrying with protocol extension flag */
613 p_i93->state = RW_I93_STATE_BUSY;
614 return;
615 }
616 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800617
Raphael Collado867d5c32017-03-27 12:49:40 +0200618 case I93_CMD_EXT_GET_SYS_INFO:
619
Jack Yu790603c2019-01-28 20:29:31 +0800620 if (rw_i93_process_ext_sys_info(p, length)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200621 rw_data.i93_sys_info.status = NFC_STATUS_OK;
622 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
623 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
624 rw_data.i93_sys_info.afi = p_i93->afi;
625 rw_data.i93_sys_info.num_block = p_i93->num_block;
626 rw_data.i93_sys_info.block_size = p_i93->block_size;
627 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
628
629 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
630
George Changff05f952021-03-15 05:51:51 +0000631 p_i93->i93_t5t_mode = RW_I93_GET_SYS_INFO_MEM_INFO;
Raphael Collado867d5c32017-03-27 12:49:40 +0200632 event = RW_I93_SYS_INFO_EVT;
633 } else {
634 /* retrying with protocol extension flag or with extended sys info
635 * command */
636 p_i93->state = RW_I93_STATE_BUSY;
637 return;
638 }
639 break;
640
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800641 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800642 break;
643 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800644
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800645 rw_cb.tcb.i93.sent_cmd = 0;
646 if (event != RW_I93_MAX_EVT) {
647 (*(rw_cb.p_cback))(event, &rw_data);
648 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700649 LOG(ERROR) << StringPrintf("Invalid response");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800650 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800651}
652
653/*******************************************************************************
654**
655** Function rw_i93_send_to_lower
656**
657** Description Send Request frame to lower layer
658**
659** Returns TRUE if success
660**
661*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800662bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800663 /* store command for retransmitting */
664 if (rw_cb.tcb.i93.p_retry_cmd) {
665 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
Yi Kong805e3612018-07-25 14:07:29 -0700666 rw_cb.tcb.i93.p_retry_cmd = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800667 }
Evan Chu85b7e842013-01-18 11:02:50 -0500668
Alisher Alikhodjaev14331cf2021-01-14 16:58:56 -0800669 uint16_t msg_size = sizeof(NFC_HDR) + p_msg->offset + p_msg->len;
670
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800671 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
Evan Chu85b7e842013-01-18 11:02:50 -0500672
Alisher Alikhodjaev14331cf2021-01-14 16:58:56 -0800673 if (rw_cb.tcb.i93.p_retry_cmd &&
674 GKI_get_pool_bufsize(NFC_RW_POOL_ID) >= msg_size) {
675 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg, msg_size);
676 } else {
677 LOG(ERROR) << StringPrintf("Memory allocation error");
678 android_errorWriteLog(0x534e4554, "157650357");
679 return false;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800680 }
Evan Chu85b7e842013-01-18 11:02:50 -0500681
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800682 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700683 LOG(ERROR) << StringPrintf("failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800684 return false;
685 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800687 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
688 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800689
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800690 return true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800691}
692
693/*******************************************************************************
694**
695** Function rw_i93_send_cmd_inventory
696**
697** Description Send Inventory Request to VICC
698**
699** Returns tNFC_STATUS
700**
701*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800702tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
703 uint8_t afi) {
704 NFC_HDR* p_cmd;
705 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800706
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700707 DLOG_IF(INFO, nfc_debug_enabled)
708 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800709
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800710 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800711
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800712 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700713 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800714 return NFC_STATUS_NO_BUFFERS;
715 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800716
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800717 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
718 p_cmd->len = 3;
719 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800720
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800721 /* Flags */
722 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
723 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
724 if (including_afi) {
725 flags |= I93_FLAG_AFI_PRESENT;
726 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700727
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800728 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800729
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800730 /* Command Code */
731 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800732
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800733 if (including_afi) {
734 /* Parameters */
735 UINT8_TO_STREAM(p, afi); /* Optional AFI */
736 p_cmd->len++;
737 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700738
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800739 if (p_uid) {
740 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
741 ARRAY8_TO_STREAM(p, p_uid); /* UID */
742 p_cmd->len += I93_UID_BYTE_LEN;
743 } else {
744 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
745 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800746
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800747 if (rw_i93_send_to_lower(p_cmd)) {
748 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
749 return NFC_STATUS_OK;
750 } else {
751 return NFC_STATUS_FAILED;
752 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800753}
754
755/*******************************************************************************
756**
757** Function rw_i93_send_cmd_stay_quiet
758**
759** Description Send Stay Quiet Request to VICC
760**
761** Returns tNFC_STATUS
762**
763*******************************************************************************/
Arach MOHAMMED BRAHIM559c7d42020-10-09 14:24:20 +0200764tNFC_STATUS rw_i93_send_cmd_stay_quiet(uint8_t* p_uid) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800765 NFC_HDR* p_cmd;
766 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800767
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700768 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800770 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800771
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800772 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700773 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800774 return NFC_STATUS_NO_BUFFERS;
775 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800776
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800777 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
778 p_cmd->len = 10;
779 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800780
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800781 /* Flags */
782 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
783 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800785 /* Command Code */
786 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800787
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800788 /* Parameters */
Arach MOHAMMED BRAHIM559c7d42020-10-09 14:24:20 +0200789 /* Beware the UID is provided with the same order as the transmission
790 one (LSB first) */
791 ARRAY_TO_STREAM(p, p_uid, I93_UID_BYTE_LEN); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800792
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800793 if (rw_i93_send_to_lower(p_cmd)) {
794 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800795
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800796 /* restart timer for stay quiet */
797 nfc_start_quick_timer(
798 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
799 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
800 return NFC_STATUS_OK;
801 } else {
802 return NFC_STATUS_FAILED;
803 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800804}
805
806/*******************************************************************************
807**
808** Function rw_i93_send_cmd_read_single_block
809**
810** Description Send Read Single Block Request to VICC
811**
812** Returns tNFC_STATUS
813**
814*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800815tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
816 bool read_security) {
817 NFC_HDR* p_cmd;
818 uint8_t *p, flags;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100819 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800820
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700821 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800822
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800823 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800824
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800825 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700826 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800827 return NFC_STATUS_NO_BUFFERS;
828 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800829
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800830 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100831 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED)
832 p_cmd->len = 11;
833 else
834 p_cmd->len = 3;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800835 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800836
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800837 /* Flags */
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +0100838 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED) {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100839 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
840 RW_I93_FLAG_DATA_RATE);
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +0100841 } else {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100842 flags = (RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500843
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +0100844 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SELECTED_STATE)
845 flags |= I93_FLAG_SELECT_SET;
846 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800847 if (read_security) flags |= I93_FLAG_OPTION_SET;
Evan Chu85b7e842013-01-18 11:02:50 -0500848
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800849 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
850 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500851
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800852 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800853
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800854 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200855 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
856 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_SINGLE_BLOCK);
857 } else {
858 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
859 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800860
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800861 /* Parameters */
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100862 if (flags & I93_FLAG_ADDRESS_SET)
863 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500864
Raphael Collado867d5c32017-03-27 12:49:40 +0200865 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
866 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800867 UINT16_TO_STREAM(p, block_number); /* Block number */
868 p_cmd->len++;
869 } else {
870 UINT8_TO_STREAM(p, block_number); /* Block number */
871 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800872
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800873 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200874 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
875 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_SINGLE_BLOCK;
876 else
877 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800878 return NFC_STATUS_OK;
879 } else {
880 return NFC_STATUS_FAILED;
881 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800882}
883
884/*******************************************************************************
885**
886** Function rw_i93_send_cmd_write_single_block
887**
888** Description Send Write Single Block Request to VICC
889**
890** Returns tNFC_STATUS
891**
892*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800893tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
894 uint8_t* p_data) {
895 NFC_HDR* p_cmd;
896 uint8_t *p, flags;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100897 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800898
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700899 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800900
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800901 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800902
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800903 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700904 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800905 return NFC_STATUS_NO_BUFFERS;
906 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800907
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800908 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100909 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED)
910 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
911 else
912 p_cmd->len = 3 + rw_cb.tcb.i93.block_size;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800913 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800914
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800915 /* Flags */
916 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
917 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
918 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
919 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
920 /* Option must be set for TI tag */
921 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
922 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
923 } else {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100924 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED) {
925 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
926 RW_I93_FLAG_DATA_RATE);
927 } else {
928 flags = (RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +0100929 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SELECTED_STATE)
930 flags |= I93_FLAG_SELECT_SET;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100931 }
Arach MOHAMMED BRAHIM7a4f7162020-10-09 15:53:28 +0200932
933 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SPECIAL_FRAME) {
934 /* Option Flag bit must be set */
935 flags |= I93_FLAG_OPTION_SET;
936 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800937 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800938
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800939 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
940 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500941
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800942 UINT8_TO_STREAM(p, flags);
Evan Chu85b7e842013-01-18 11:02:50 -0500943
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800944 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200945 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
946 UINT8_TO_STREAM(p, I93_CMD_EXT_WRITE_SINGLE_BLOCK);
947 } else {
948 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
949 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800950
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800951 /* Parameters */
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100952 if (flags & I93_FLAG_ADDRESS_SET)
953 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500954
Raphael Collado867d5c32017-03-27 12:49:40 +0200955 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
956 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800957 UINT16_TO_STREAM(p, block_number); /* Block number */
958 p_cmd->len++;
959 } else {
960 UINT8_TO_STREAM(p, block_number); /* Block number */
961 }
Evan Chu85b7e842013-01-18 11:02:50 -0500962
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800963 /* Data */
964 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800965
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800966 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200967 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
968 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_SINGLE_BLOCK;
969 else
970 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800971 return NFC_STATUS_OK;
972 } else {
973 return NFC_STATUS_FAILED;
974 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800975}
976
977/*******************************************************************************
978**
979** Function rw_i93_send_cmd_lock_block
980**
981** Description Send Lock Block Request to VICC
982**
Olivier Lorente487e6d12021-04-27 16:13:23 +0200983** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R,
984** M24LR16D-W do not support.
Evan Chu85b7e842013-01-18 11:02:50 -0500985**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800986** Returns tNFC_STATUS
987**
988*******************************************************************************/
Arach MOHAMMED BRAHIM1b7be952020-10-09 15:45:48 +0200989tNFC_STATUS rw_i93_send_cmd_lock_block(uint16_t block_number) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800990 NFC_HDR* p_cmd;
991 uint8_t* p;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +0100992 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
993 uint8_t flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800994
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700995 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800996
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800997 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800998
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800999 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001000 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001001 return NFC_STATUS_NO_BUFFERS;
1002 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001003
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001004 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001005 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED)
1006 p_cmd->len = 11;
1007 else
1008 p_cmd->len = 3;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001009 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001010
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001011 /* Flags */
1012 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
1013 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
1014 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1015 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
1016 /* Option must be set for TI tag */
1017 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
1018 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
1019 } else {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001020 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED) {
1021 /* Address Mode Selector must be set */
1022 flags = I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1023 RW_I93_FLAG_DATA_RATE;
1024 } else {
1025 flags = RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE;
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01001026
1027 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SELECTED_STATE)
1028 flags |= I93_FLAG_SELECT_SET;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001029 }
Arach MOHAMMED BRAHIM7a4f7162020-10-09 15:53:28 +02001030 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SPECIAL_FRAME) {
1031 /* Option Flag bit must be set */
1032 flags |= I93_FLAG_OPTION_SET;
1033 }
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001034 UINT8_TO_STREAM(p, flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001035 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001036
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001037 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001038 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1039 UINT8_TO_STREAM(p, I93_CMD_EXT_LOCK_BLOCK);
1040 } else {
1041 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
1042 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001043
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001044 /* Parameters */
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001045 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED)
1046 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +02001047
1048 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Arach MOHAMMED BRAHIM1b7be952020-10-09 15:45:48 +02001049 UINT16_TO_STREAM(p, block_number); /* Block number */
Raphael Collado867d5c32017-03-27 12:49:40 +02001050 p_cmd->len++;
1051 } else {
1052 UINT8_TO_STREAM(p, block_number); /* Block number */
1053 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001054
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001055 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001056 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1057 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_LOCK_BLOCK;
1058 else
1059 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001060 return NFC_STATUS_OK;
1061 } else {
1062 return NFC_STATUS_FAILED;
1063 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001064}
1065
1066/*******************************************************************************
1067**
1068** Function rw_i93_send_cmd_read_multi_blocks
1069**
1070** Description Send Read Multiple Blocks Request to VICC
1071**
1072** Returns tNFC_STATUS
1073**
1074*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001075tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
1076 uint16_t number_blocks) {
1077 NFC_HDR* p_cmd;
1078 uint8_t *p, flags;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001079 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001080
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001081 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001082
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001083 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001085 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001086 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001087 return NFC_STATUS_NO_BUFFERS;
1088 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001089
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001090 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001091 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED)
1092 p_cmd->len = 12;
1093 else
1094 p_cmd->len = 4;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001095 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001096
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001097 /* Flags */
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01001098 if (p_i93->addr_mode == RW_I93_MODE_ADDRESSED) {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001099 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1100 RW_I93_FLAG_DATA_RATE);
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01001101 } else {
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001102 flags = (RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -05001103
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01001104 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_SELECTED_STATE)
1105 flags |= I93_FLAG_SELECT_SET;
1106 }
1107
Raphael Collado867d5c32017-03-27 12:49:40 +02001108 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001109 flags |= I93_FLAG_PROT_EXT_YES;
Raphael Collado867d5c32017-03-27 12:49:40 +02001110 }
Evan Chu85b7e842013-01-18 11:02:50 -05001111
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001112 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001113
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001114 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001115 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1116 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_MULTI_BLOCK);
1117 } else {
1118 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
1119 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001120
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001121 /* Parameters */
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01001122 if (flags & I93_FLAG_ADDRESS_SET)
1123 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001124
Raphael Collado867d5c32017-03-27 12:49:40 +02001125 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1126 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001127 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1128 p_cmd->len++;
1129 } else {
1130 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1131 }
Evan Chu85b7e842013-01-18 11:02:50 -05001132
Raphael Collado867d5c32017-03-27 12:49:40 +02001133 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1134 UINT16_TO_STREAM(
1135 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1136 p_cmd->len++;
1137 } else {
1138 UINT8_TO_STREAM(
1139 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1140 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001141
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001142 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001143 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1144 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_MULTI_BLOCK;
1145 else
1146 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001147 return NFC_STATUS_OK;
1148 } else {
1149 return NFC_STATUS_FAILED;
1150 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001151}
1152
1153/*******************************************************************************
1154**
1155** Function rw_i93_send_cmd_write_multi_blocks
1156**
1157** Description Send Write Multiple Blocks Request to VICC
1158**
1159** Returns tNFC_STATUS
1160**
1161*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02001162tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001163 uint16_t number_blocks,
1164 uint8_t* p_data) {
1165 NFC_HDR* p_cmd;
1166 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001167
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001168 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001169
Alisher Alikhodjaev24a570b2020-06-18 15:44:19 -07001170 if (number_blocks * rw_cb.tcb.i93.block_size >
1171 GKI_get_pool_bufsize(NFC_RW_POOL_ID) - NCI_MSG_OFFSET_SIZE -
1172 NCI_DATA_HDR_SIZE - 1 -
1173 (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS ? 2 : 0) - 12) {
1174 android_errorWriteLog(0x534e4554, "157650365");
1175 return NFC_STATUS_FAILED;
1176 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001177 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001179 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001180 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001181 return NFC_STATUS_NO_BUFFERS;
1182 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001183
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001184 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1185 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
1186 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001187
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001188 /* Flags */
1189 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1190 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001192 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001193 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1194 INT8_TO_STREAM(p, I93_CMD_EXT_WRITE_MULTI_BLOCK);
1195 } else {
1196 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
1197 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001198
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001199 /* Parameters */
1200 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +02001201 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1202 UINT16_TO_STREAM(p, first_block_number); /* Block number */
1203 UINT16_TO_STREAM(
1204 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1205 p_cmd->len += 2;
1206 } else {
1207 UINT8_TO_STREAM(p, first_block_number); /* Block number */
1208 UINT8_TO_STREAM(
1209 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1210 }
1211
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001212 /* Data */
1213 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001214
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001215 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001216 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1217 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_MULTI_BLOCK;
1218 else
1219 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001220 return NFC_STATUS_OK;
1221 } else {
1222 return NFC_STATUS_FAILED;
1223 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001224}
1225
1226/*******************************************************************************
1227**
1228** Function rw_i93_send_cmd_select
1229**
1230** Description Send Select Request to VICC
1231**
1232** Returns tNFC_STATUS
1233**
1234*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001235tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1236 NFC_HDR* p_cmd;
1237 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001238
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001239 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001240
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001241 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001242
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001243 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001244 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001245 return NFC_STATUS_NO_BUFFERS;
1246 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001247
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001248 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1249 p_cmd->len = 10;
1250 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001251
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001252 /* Flags */
1253 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1254 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001255
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001256 /* Command Code */
1257 UINT8_TO_STREAM(p, I93_CMD_SELECT);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001258
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001259 /* Parameters */
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01001260 /* Beware the UID is provided with the same order as the transmission
1261 one (LSB first) */
1262 ARRAY_TO_STREAM(p, p_uid, I93_UID_BYTE_LEN); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001263
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001264 if (rw_i93_send_to_lower(p_cmd)) {
1265 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1266 return NFC_STATUS_OK;
1267 } else {
1268 return NFC_STATUS_FAILED;
1269 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001270}
1271
1272/*******************************************************************************
1273**
1274** Function rw_i93_send_cmd_reset_to_ready
1275**
1276** Description Send Reset to Ready Request to VICC
1277**
1278** Returns tNFC_STATUS
1279**
1280*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001281tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1282 NFC_HDR* p_cmd;
1283 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001284
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001285 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001286
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001287 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001288
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001289 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001290 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001291 return NFC_STATUS_NO_BUFFERS;
1292 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001293
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001294 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1295 p_cmd->len = 10;
1296 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001298 /* Flags */
1299 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1300 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001301
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001302 /* Command Code */
1303 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001304
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001305 /* Parameters */
1306 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001307
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001308 if (rw_i93_send_to_lower(p_cmd)) {
1309 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1310 return NFC_STATUS_OK;
1311 } else {
1312 return NFC_STATUS_FAILED;
1313 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001314}
1315
1316/*******************************************************************************
1317**
1318** Function rw_i93_send_cmd_write_afi
1319**
1320** Description Send Write AFI Request to VICC
1321**
1322** Returns tNFC_STATUS
1323**
1324*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001325tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1326 NFC_HDR* p_cmd;
1327 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001328
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001329 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001330
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001331 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001332
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001333 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001334 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001335 return NFC_STATUS_NO_BUFFERS;
1336 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001337
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001338 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1339 p_cmd->len = 11;
1340 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001341
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001342 /* Flags */
1343 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1344 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001345
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001346 /* Command Code */
1347 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001348
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001349 /* Parameters */
1350 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1351 UINT8_TO_STREAM(p, afi); /* AFI */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001352
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001353 if (rw_i93_send_to_lower(p_cmd)) {
1354 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1355 return NFC_STATUS_OK;
1356 } else {
1357 return NFC_STATUS_FAILED;
1358 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001359}
1360
1361/*******************************************************************************
1362**
1363** Function rw_i93_send_cmd_lock_afi
1364**
1365** Description Send Lock AFI Request to VICC
1366**
1367** Returns tNFC_STATUS
1368**
1369*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001370tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1371 NFC_HDR* p_cmd;
1372 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001373
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001374 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001375
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001376 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001377
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001378 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001379 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001380 return NFC_STATUS_NO_BUFFERS;
1381 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001382
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001383 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1384 p_cmd->len = 10;
1385 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001386
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001387 /* Flags */
1388 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1389 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001390
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001391 /* Command Code */
1392 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001393
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001394 /* Parameters */
1395 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001396
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001397 if (rw_i93_send_to_lower(p_cmd)) {
1398 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1399 return NFC_STATUS_OK;
1400 } else {
1401 return NFC_STATUS_FAILED;
1402 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001403}
1404
1405/*******************************************************************************
1406**
1407** Function rw_i93_send_cmd_write_dsfid
1408**
1409** Description Send Write DSFID Request to VICC
1410**
1411** Returns tNFC_STATUS
1412**
1413*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001414tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1415 NFC_HDR* p_cmd;
1416 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001417
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001418 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001419
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001420 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001421
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001422 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001423 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001424 return NFC_STATUS_NO_BUFFERS;
1425 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001426
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001427 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1428 p_cmd->len = 11;
1429 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001430
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001431 /* Flags */
1432 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1433 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001434
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001435 /* Command Code */
1436 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001437
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001438 /* Parameters */
1439 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1440 UINT8_TO_STREAM(p, dsfid); /* DSFID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001441
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001442 if (rw_i93_send_to_lower(p_cmd)) {
1443 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1444 return NFC_STATUS_OK;
1445 } else {
1446 return NFC_STATUS_FAILED;
1447 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001448}
1449
1450/*******************************************************************************
1451**
1452** Function rw_i93_send_cmd_lock_dsfid
1453**
1454** Description Send Lock DSFID Request to VICC
1455**
1456** Returns tNFC_STATUS
1457**
1458*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001459tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1460 NFC_HDR* p_cmd;
1461 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001462
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001463 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001464
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001465 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001466
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001467 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001468 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001469 return NFC_STATUS_NO_BUFFERS;
1470 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001471
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001472 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1473 p_cmd->len = 10;
1474 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001475
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001476 /* Flags */
1477 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1478 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001479
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001480 /* Command Code */
1481 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001482
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001483 /* Parameters */
1484 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001485
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001486 if (rw_i93_send_to_lower(p_cmd)) {
1487 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1488 return NFC_STATUS_OK;
1489 } else {
1490 return NFC_STATUS_FAILED;
1491 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001492}
1493
1494/*******************************************************************************
1495**
Raphael Collado867d5c32017-03-27 12:49:40 +02001496** Function rw_i93_send_cmd_get_ext_sys_info
1497**
1498** Description Send Get Extended System Information Request to VICC
1499**
1500** Returns tNFC_STATUS
1501**
1502*******************************************************************************/
1503tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid) {
1504 NFC_HDR* p_cmd;
1505 uint8_t* p;
1506
1507 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1508
1509 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1510
1511 if (!p_cmd) {
1512 DLOG_IF(INFO, nfc_debug_enabled) << __func__ << "Cannot allocate buffer";
1513 return NFC_STATUS_NO_BUFFERS;
1514 }
1515
1516 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1517 p_cmd->len = 11;
1518 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1519
1520 /* Flags */
1521 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1522 RW_I93_FLAG_DATA_RATE));
1523
1524 /* Command Code */
1525 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_SYS_INFO);
1526
1527 /* Parameters request field */
1528 UINT8_TO_STREAM(p,
1529 (I93_INFO_FLAG_MOI | I93_INFO_FLAG_DSFID | I93_INFO_FLAG_AFI |
1530 I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_IC_REF));
1531
1532 /* Parameters */
1533 if (p_uid) {
1534 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1535 } else {
1536 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1537 }
1538
1539 if (rw_i93_send_to_lower(p_cmd)) {
1540 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_SYS_INFO;
1541 return NFC_STATUS_OK;
1542 } else {
1543 return NFC_STATUS_FAILED;
1544 }
1545}
1546
1547/*******************************************************************************
1548**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001549** Function rw_i93_send_cmd_get_sys_info
1550**
1551** Description Send Get System Information Request to VICC
1552**
1553** Returns tNFC_STATUS
1554**
1555*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001556tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1557 NFC_HDR* p_cmd;
1558 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001559
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001560 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001561
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001562 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001563
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001564 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001565 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001566 return NFC_STATUS_NO_BUFFERS;
1567 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001568
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001569 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1570 p_cmd->len = 10;
1571 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001572
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001573 /* Flags */
1574 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1575 RW_I93_FLAG_DATA_RATE | extra_flags));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001576
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001577 /* Command Code */
1578 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001579
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001580 /* Parameters */
1581 if (p_uid) {
1582 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1583 } else {
1584 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1585 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001586
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001587 if (rw_i93_send_to_lower(p_cmd)) {
1588 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1589 return NFC_STATUS_OK;
1590 } else {
1591 return NFC_STATUS_FAILED;
1592 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001593}
1594
1595/*******************************************************************************
1596**
1597** Function rw_i93_send_cmd_get_multi_block_sec
1598**
1599** Description Send Get Multiple Block Security Status Request to VICC
1600**
1601** Returns tNFC_STATUS
1602**
1603*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001604tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1605 uint16_t number_blocks) {
1606 NFC_HDR* p_cmd;
1607 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001608
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001609 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001610
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001611 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001612
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001613 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001614 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001615 return NFC_STATUS_NO_BUFFERS;
1616 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001617
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001618 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1619 p_cmd->len = 12;
1620 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001621
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001622 /* Flags */
1623 flags =
1624 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -05001625
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001626 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1627 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -05001628
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001629 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001630
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001631 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001632 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1633 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_MULTI_BLK_SEC);
1634 } else {
1635 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1636 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001637
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001638 /* Parameters */
1639 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001640
Raphael Collado867d5c32017-03-27 12:49:40 +02001641 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1642 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001643 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1644 UINT16_TO_STREAM(
1645 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1646 p_cmd->len += 2;
1647 } else {
1648 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1649 UINT8_TO_STREAM(
1650 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1651 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001652
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001653 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001654 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1655 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_MULTI_BLK_SEC;
1656 else
1657 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001658 return NFC_STATUS_OK;
1659 } else {
1660 return NFC_STATUS_FAILED;
1661 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001662}
1663
1664/*******************************************************************************
1665**
1666** Function rw_i93_get_next_blocks
1667**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001668** Description Read as many blocks as possible (up to
1669** RW_I93_READ_MULTI_BLOCK_SIZE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001670**
1671** Returns tNFC_STATUS
1672**
1673*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001674tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1675 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1676 uint16_t first_block;
1677 uint16_t num_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001678
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001679 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001680
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001681 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001683 /* more blocks, more efficent but more error rate */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001684
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001685 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1686 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001687
George Changff05f952021-03-15 05:51:51 +00001688 // first_block is an offset related to the beginning of the T5T_Area for T5T
1689 // tags but physical memory for ISO15693 tags
1690 if (p_i93->i93_t5t_mode == RW_I93_GET_SYS_INFO_MEM_INFO) {
1691 if (num_block + first_block > p_i93->num_block)
1692 num_block = p_i93->num_block - first_block;
1693 } else {
1694 if (num_block + first_block >
1695 p_i93->num_block + p_i93->t5t_area_start_block)
1696 num_block =
1697 p_i93->num_block - first_block + p_i93->t5t_area_start_block;
1698 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001699
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001700 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
Olivier Lorente487e6d12021-04-27 16:13:23 +02001701 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR16D-W, M24LR64E-R
1702 ** require
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001703 ** - The max number of blocks is 32 and they are all located in the
1704 ** same sector.
1705 ** - The sector is 32 blocks of 4 bytes.
1706 */
1707 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1708 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1709 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1710 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
Olivier Lorente487e6d12021-04-27 16:13:23 +02001711 (p_i93->product_version == RW_I93_STM_M24LR16D_W) ||
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001712 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1713 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1714 num_block = I93_STM_MAX_BLOCKS_PER_READ;
Evan Chu85b7e842013-01-18 11:02:50 -05001715
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001716 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1717 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1718 num_block = I93_STM_BLOCKS_PER_SECTOR -
1719 (first_block % I93_STM_BLOCKS_PER_SECTOR);
Evan Chu85b7e842013-01-18 11:02:50 -05001720 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001721 }
1722 }
Evan Chu85b7e842013-01-18 11:02:50 -05001723
Adrian Mocanu476558f2020-02-05 09:37:41 +00001724 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_ONS) {
1725 /* N24RF04, N24RF04E, N24RF16, N24RF16E, N24RF64, N24RF64E requires
1726 ** - The max number of blocks is 32 and they are all located in the
1727 ** same sector.
1728 ** - The sector is 32 blocks of 4 bytes.
1729 */
1730 if ((p_i93->product_version == RW_I93_ONS_N36RW02) ||
1731 (p_i93->product_version == RW_I93_ONS_N24RF04) ||
1732 (p_i93->product_version == RW_I93_ONS_N24RF04E)||
1733 (p_i93->product_version == RW_I93_ONS_N24RF16) ||
1734 (p_i93->product_version == RW_I93_ONS_N24RF16E)||
1735 (p_i93->product_version == RW_I93_ONS_N24RF64) ||
1736 (p_i93->product_version == RW_I93_ONS_N24RF64E)) {
1737 if (num_block > I93_ONS_MAX_BLOCKS_PER_READ)
1738 num_block = I93_ONS_MAX_BLOCKS_PER_READ;
1739
1740 if ((first_block / I93_ONS_BLOCKS_PER_SECTOR) !=
1741 ((first_block + num_block - 1) / I93_ONS_BLOCKS_PER_SECTOR)) {
1742 num_block = I93_ONS_BLOCKS_PER_SECTOR -
1743 (first_block % I93_ONS_BLOCKS_PER_SECTOR);
1744 }
1745 }
1746 }
1747
George Changff05f952021-03-15 05:51:51 +00001748 if (num_block == 0) {
1749 /* only one remaining block to read */
1750 return rw_i93_send_cmd_read_single_block(first_block, false);
1751 }
1752
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001753 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1754 } else {
1755 return rw_i93_send_cmd_read_single_block(first_block, false);
1756 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001757}
1758
1759/*******************************************************************************
1760**
Evan Chu85b7e842013-01-18 11:02:50 -05001761** Function rw_i93_get_next_block_sec
1762**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001763** Description Get as many security of blocks as possible from
1764** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
Evan Chu85b7e842013-01-18 11:02:50 -05001765**
1766** Returns tNFC_STATUS
1767**
1768*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001769tNFC_STATUS rw_i93_get_next_block_sec(void) {
1770 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1771 uint16_t num_blocks;
Evan Chu85b7e842013-01-18 11:02:50 -05001772
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001773 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001775 if (p_i93->num_block <= p_i93->rw_offset) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001776 LOG(ERROR) << StringPrintf(
1777 "rw_offset(0x%x) must be less than num_block(0x%x)", p_i93->rw_offset,
1778 p_i93->num_block);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001779 return NFC_STATUS_FAILED;
1780 }
Evan Chu85b7e842013-01-18 11:02:50 -05001781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001782 num_blocks = p_i93->num_block - p_i93->rw_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001783
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001784 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1785 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
Evan Chu85b7e842013-01-18 11:02:50 -05001786
Raphael Collado867d5c32017-03-27 12:49:40 +02001787 DLOG_IF(INFO, nfc_debug_enabled)
1788 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001789 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
Evan Chu85b7e842013-01-18 11:02:50 -05001790}
1791
1792/*******************************************************************************
1793**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001794** Function rw_i93_sm_detect_ndef
1795**
1796** Description Process NDEF detection procedure
1797**
1798** 1. Get UID if not having yet
1799** 2. Get System Info if not having yet
1800** 3. Read first block for CC
1801** 4. Search NDEF Type and length
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001802** 5. Get block status to get max NDEF size and read-only
1803** status
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001804**
1805** Returns void
1806**
1807*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001808void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001809 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001810 uint8_t flags, u8 = 0, cc[4];
1811 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1812 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1813 tRW_DATA rw_data;
1814 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001815
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001816 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00001817 "%s - sub_state:%s (0x%x)", __func__,
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001818 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001819
Ruchi Kandoi1a6799d2019-01-24 13:39:18 -08001820 if (length == 0) {
1821 android_errorWriteLog(0x534e4554, "121260197");
1822 rw_i93_handle_error(NFC_STATUS_FAILED);
1823 return;
1824 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001825 STREAM_TO_UINT8(flags, p);
1826 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001827
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001828 if (flags & I93_FLAG_ERROR_DETECTED) {
1829 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1830 /* getting system info with protocol extension flag */
Adrian Mocanu476558f2020-02-05 09:37:41 +00001831 /* This STM & ONS tag supports more than 2040 bytes */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001832 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1833 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001834 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00001835 << StringPrintf("%s - Got error flags (0x%02x)", __func__, flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001836 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001837 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001838 return;
1839 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001840
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001841 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001842 case RW_I93_SUBSTATE_WAIT_UID:
1843
Ruchi Kandoi1a6799d2019-01-24 13:39:18 -08001844 if (length < (I93_UID_BYTE_LEN + 1)) {
1845 android_errorWriteLog(0x534e4554, "121260197");
1846 rw_i93_handle_error(NFC_STATUS_FAILED);
1847 return;
1848 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001849 STREAM_TO_UINT8(u8, p); /* DSFID */
1850 p_uid = p_i93->uid;
1851 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001852
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001853 if (u8 != I93_DFS_UNSUPPORTED) {
1854 /* if Data Storage Format is unknown */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001855 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00001856 << StringPrintf("%s - Got unknown DSFID (0x%02x)", __func__, u8);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001857 rw_i93_handle_error(NFC_STATUS_FAILED);
1858 } else {
1859 /* get system information to get memory size */
Yi Kong805e3612018-07-25 14:07:29 -07001860 if (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_NO) ==
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001861 NFC_STATUS_OK) {
1862 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1863 } else {
1864 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001865 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001866 }
1867 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001868
1869 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1870
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001871 p_i93->block_size = 0;
1872 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001873
Ruchi Kandoi451edc92019-01-24 14:45:55 -08001874 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001875 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001876 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001877 }
1878
1879 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001880 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00001881 << StringPrintf("%s - Unable to get tag memory size", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001882 rw_i93_handle_error(status);
1883 } else {
1884 /* read CC in the first block */
1885 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1886 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1887 } else {
1888 rw_i93_handle_error(NFC_STATUS_FAILED);
1889 }
1890 }
1891 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001892
1893 case RW_I93_SUBSTATE_WAIT_CC:
1894
George Chang4025e2b2019-08-16 20:37:23 +08001895 if (length < RW_I93_CC_SIZE) {
1896 android_errorWriteLog(0x534e4554, "139188579");
1897 rw_i93_handle_error(NFC_STATUS_FAILED);
1898 return;
1899 }
1900
1901 /* assume block size is more than RW_I93_CC_SIZE 4 */
1902 STREAM_TO_ARRAY(cc, p, RW_I93_CC_SIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001903
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001904 status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001905
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001906 /*
1907 ** Capability Container (CC)
1908 **
1909 ** CC[0] : magic number (0xE1)
1910 ** CC[1] : Bit 7-6:Major version number
1911 ** : Bit 5-4:Minor version number
1912 ** : Bit 3-2:Read access condition (00b: read access granted
1913 ** without any security)
1914 ** : Bit 1-0:Write access condition (00b: write access granted
1915 ** without any security)
Adrian Mocanu476558f2020-02-05 09:37:41 +00001916 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, ONS set
1917 ** to 0xFF if more than 2040bytes]
1918 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM, ONS]
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001919 ** : Bit 1:Inventory page read is supported [NXP]
Adrian Mocanu476558f2020-02-05 09:37:41 +00001920 ** : Bit 2:More than 2040 bytes are supported [STM, ONS]
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001921 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001922
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001923 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00001924 << StringPrintf("%s - cc[0-3]: 0x%02X 0x%02X 0x%02X 0x%02X", __func__,
1925 cc[0], cc[1], cc[2], cc[3]);
1926
1927 DLOG_IF(INFO, nfc_debug_enabled)
1928 << StringPrintf("%s - Total blocks:0x%04X, Block size:0x%02X",
1929 __func__, p_i93->num_block, p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001930
Raphael Collado867d5c32017-03-27 12:49:40 +02001931 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1932 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
Arach MOHAMMED BRAHIMe9e96532020-10-09 15:50:44 +02001933 if ((cc[1] & 0xC0) > I93_VERSION_1_x) {
1934 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1935 "%s - Major mapping version above 1 %d.x", __func__, cc[1] >> 6);
1936 /* major mapping version above 1 not supported */
1937 rw_i93_handle_error(NFC_STATUS_FAILED);
1938 break;
1939 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001940 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1941 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1942 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1943 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1944 /* read-only or password required to write */
1945 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1946 }
1947 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
George Changff05f952021-03-15 05:51:51 +00001948 /* tag supports read multiple blocks command */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001949 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1950 }
Arach MOHAMMED BRAHIM7a4f7162020-10-09 15:53:28 +02001951 if (cc[3] & I93_ICODE_CC_SPECIAL_FRAME_MASK) {
1952 /* tag supports Special Frame for Write-Alike commands */
1953 p_i93->intl_flags |= RW_I93_FLAG_SPECIAL_FRAME;
1954 }
Raphael Collado867d5c32017-03-27 12:49:40 +02001955 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1956 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1957 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001958 status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001959 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001960 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001961
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001962 if (status == NFC_STATUS_OK) {
1963 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1964 */
1965 if (cc[2] != 0)
1966 p_i93->rw_offset = 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001967 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001968 p_i93->rw_offset = 8;
1969
1970 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1971 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1972 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1973 } else {
1974 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001975 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001976 } else {
1977 rw_i93_handle_error(NFC_STATUS_FAILED);
1978 }
1979 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001980
1981 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1982
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001983 /* search TLV within read blocks */
1984 for (xx = 0; xx < length; xx++) {
1985 /* if looking for type */
1986 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1987 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1988 continue;
1989 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1990 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1991 /* store found type and get length field */
1992 p_i93->tlv_type = *(p + xx);
1993 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001994
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001995 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1996 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1997 /* no NDEF TLV found */
1998 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1999 break;
2000 } else {
George Changff05f952021-03-15 05:51:51 +00002001 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2002 "%s - Invalid type: 0x%02x", __func__, *(p + xx));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002003 rw_i93_handle_error(NFC_STATUS_FAILED);
2004 return;
2005 }
2006 } else if (p_i93->tlv_detect_state ==
2007 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
2008 /* if 3 bytes length field */
2009 if (*(p + xx) == 0xFF) {
2010 /* need 2 more bytes for length field */
2011 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
2012 } else {
2013 p_i93->tlv_length = *(p + xx);
2014 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
2015
2016 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
2017 p_i93->ndef_tlv_last_offset =
2018 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
2019 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002020 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002021 }
2022 } else if (p_i93->tlv_detect_state ==
2023 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
2024 /* the second byte of 3 bytes length field */
2025 p_i93->tlv_length = *(p + xx);
2026 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
2027 } else if (p_i93->tlv_detect_state ==
2028 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
2029 /* the last byte of 3 bytes length field */
2030 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
2031 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002032
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002033 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
2034 p_i93->ndef_tlv_last_offset =
2035 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
2036 break;
2037 }
2038 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
2039 /* this is other than NDEF TLV */
2040 if (p_i93->tlv_length <= length - xx) {
2041 /* skip value field */
2042 xx += (uint8_t)p_i93->tlv_length;
2043 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
2044 } else {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002045 /* read more data */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002046 p_i93->tlv_length -= (length - xx);
2047 break;
2048 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002049 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002050 }
2051
2052 /* found NDEF TLV and read length field */
2053 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
2054 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
2055 p_i93->ndef_length = p_i93->tlv_length;
2056
2057 /* get lock status to see if read-only */
2058 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2059 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2060 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2061 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2062 /* these doesn't support GetMultiBlockSecurityStatus */
2063
2064 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2065 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
2066
2067 /* read block to get lock status */
2068 rw_i93_send_cmd_read_single_block(first_block, true);
2069 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
2070 } else {
2071 /* block offset for read-only check */
2072 p_i93->rw_offset = 0;
2073
2074 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2075 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
2076 } else {
2077 rw_i93_handle_error(NFC_STATUS_FAILED);
2078 }
2079 }
2080 } else {
2081 /* read more data */
2082 p_i93->rw_offset += length;
2083
2084 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
2085 rw_i93_handle_error(NFC_STATUS_FAILED);
2086 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
2087 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
2088 } else {
2089 rw_i93_handle_error(NFC_STATUS_FAILED);
2090 }
2091 }
2092 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002093
2094 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
2095
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002096 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2097 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2098 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2099 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2100 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002101
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002102 block = (p_i93->rw_offset / p_i93->block_size);
2103 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002104
Jack Yuafd41fb2020-03-18 20:14:05 +08002105 if (length == 0) {
2106 rw_i93_handle_error(NFC_STATUS_FAILED);
2107 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002108 if ((*p) & I93_BLOCK_LOCKED) {
2109 if (block <= last_block) {
2110 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2111 }
2112 } else {
2113 /* if we need to check more user blocks */
2114 if (block + 1 < p_i93->num_block) {
2115 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002116
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002117 /* read block to get lock status */
2118 rw_i93_send_cmd_read_single_block(
2119 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2120 break;
2121 }
Evan Chu85b7e842013-01-18 11:02:50 -05002122 }
2123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002124 p_i93->max_ndef_length =
2125 p_i93->ndef_length
2126 /* add available bytes including the last block of NDEF TLV */
2127 + (p_i93->block_size * (block - last_block) + 1) -
2128 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
2129 } else {
2130 if (p_i93->rw_offset == 0) {
2131 p_i93->max_ndef_length =
2132 p_i93->ndef_length
2133 /* add available bytes in the last block of NDEF TLV */
2134 + p_i93->block_size -
2135 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
2136
2137 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
2138 } else {
2139 first_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002140 }
2141
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002142 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
2143 num_blocks = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002144
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002145 for (block = first_block; block < num_blocks; block++) {
2146 /* if any block of NDEF TLV is locked */
2147 if ((block + p_i93->rw_offset) <= last_block) {
2148 if (*(p + block) & I93_BLOCK_LOCKED) {
2149 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2150 break;
2151 }
2152 } else {
2153 if (*(p + block) & I93_BLOCK_LOCKED) {
2154 /* no more consecutive unlocked block */
2155 break;
2156 } else {
2157 /* add block size if not locked */
2158 p_i93->max_ndef_length += p_i93->block_size;
2159 }
2160 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002161 }
2162
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002163 /* update next security of block to check */
2164 p_i93->rw_offset += num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002165
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002166 /* if need to check more */
2167 if (p_i93->num_block > p_i93->rw_offset) {
2168 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2169 rw_i93_handle_error(NFC_STATUS_FAILED);
2170 }
2171 break;
2172 }
2173 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002174
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002175 /* check if need to adjust max NDEF length */
2176 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
2177 /* 3 bytes length field must be used */
2178 p_i93->max_ndef_length -= 2;
2179 }
2180
2181 rw_data.ndef.status = NFC_STATUS_OK;
Love Khanna57a3dfa2017-03-28 20:03:38 +05302182 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002183 rw_data.ndef.flags = 0;
2184 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
2185 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
2186 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2187 rw_data.ndef.cur_size = p_i93->ndef_length;
2188
2189 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
2190 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
2191 rw_data.ndef.max_size = p_i93->ndef_length;
2192 } else {
2193 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
2194 rw_data.ndef.max_size = p_i93->max_ndef_length;
2195 }
2196
2197 p_i93->state = RW_I93_STATE_IDLE;
2198 p_i93->sent_cmd = 0;
2199
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002200 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00002201 "%s - NDEF cur_size(%d),max_size (%d), flags (0x%x)", __func__,
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002202 rw_data.ndef.cur_size, rw_data.ndef.max_size, rw_data.ndef.flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002203
2204 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
2205 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002206
2207 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002208 break;
2209 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002210}
2211
2212/*******************************************************************************
2213**
2214** Function rw_i93_sm_read_ndef
2215**
2216** Description Process NDEF read procedure
2217**
2218** Returns void
2219**
2220*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002221void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
2222 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2223 uint8_t flags;
2224 uint16_t offset, length = p_resp->len;
2225 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2226 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002227
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002228 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002229
Jack Yu790603c2019-01-28 20:29:31 +08002230 if (length == 0) {
2231 android_errorWriteLog(0x534e4554, "122035770");
Jack Yuf0afca02019-01-31 08:21:04 +08002232 rw_i93_handle_error(NFC_STATUS_FAILED);
Jack Yu790603c2019-01-28 20:29:31 +08002233 return;
2234 }
2235
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002236 STREAM_TO_UINT8(flags, p);
2237 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002238
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002239 if (flags & I93_FLAG_ERROR_DETECTED) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002240 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00002241 << StringPrintf("%s - Got error flags (0x%02x)", __func__, flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002242 rw_i93_handle_error(NFC_STATUS_FAILED);
2243 return;
2244 }
2245
2246 /* if this is the first block */
2247 if (p_i93->rw_length == 0) {
2248 /* get start of NDEF in the first block */
2249 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
2250
2251 if (p_i93->ndef_length < 0xFF) {
2252 offset += 2;
2253 } else {
2254 offset += 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002255 }
2256
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002257 /* adjust offset if read more blocks because the first block doesn't have
2258 * NDEF */
2259 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
2260 } else {
2261 offset = 0;
2262 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002263
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002264 /* if read enough data to skip type and length field for the beginning */
2265 if (offset < length) {
2266 offset++; /* flags */
2267 p_resp->offset += offset;
2268 p_resp->len -= offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002270 rw_data.data.status = NFC_STATUS_OK;
2271 rw_data.data.p_data = p_resp;
2272
2273 p_i93->rw_length += p_resp->len;
2274 } else {
2275 /* in case of no Ndef data included */
2276 p_resp->len = 0;
2277 }
2278
2279 /* if read all of NDEF data */
2280 if (p_i93->rw_length >= p_i93->ndef_length) {
2281 /* remove extra btyes in the last block */
2282 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2283
2284 p_i93->state = RW_I93_STATE_IDLE;
2285 p_i93->sent_cmd = 0;
2286
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002287 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00002288 << StringPrintf("%s - NDEF read complete read (%d)/total (%d)",
2289 __func__, p_resp->len, p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002290
2291 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2292 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002293 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00002294 << StringPrintf("%s - NDEF read segment read (%d)/total (%d)", __func__,
2295 p_resp->len, p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002296
2297 if (p_resp->len > 0) {
2298 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002299 }
2300
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002301 /* this will make read data from next block */
2302 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002304 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2305 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002306 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002307 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002308}
2309
2310/*******************************************************************************
2311**
2312** Function rw_i93_sm_update_ndef
2313**
2314** Description Process NDEF update procedure
2315**
2316** 1. Set length field to zero
2317** 2. Write NDEF and Terminator TLV
2318** 3. Set length field to NDEF length
2319**
2320** Returns void
2321**
2322*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002323void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
2324 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2325 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2326 uint16_t length = p_resp->len, block_number;
2327 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2328 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002329
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002330 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00002331 "%s - sub_state:%s (0x%x)", __func__,
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002332 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002333
Jack Yu790603c2019-01-28 20:29:31 +08002334 if (length == 0 || p_i93->block_size > I93_MAX_BLOCK_LENGH) {
2335 android_errorWriteLog(0x534e4554, "122320256");
2336 rw_i93_handle_error(NFC_STATUS_FAILED);
2337 return;
2338 }
2339
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002340 STREAM_TO_UINT8(flags, p);
2341 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002342
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002343 if (flags & I93_FLAG_ERROR_DETECTED) {
2344 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2345 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2346 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2347 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2348 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2349 /* ignore error */
2350 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002351 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00002352 << StringPrintf("%s - Got error flags (0x%02x)", __func__, flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002353 rw_i93_handle_error(NFC_STATUS_FAILED);
2354 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002355 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002356 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002357
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002358 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002359 case RW_I93_SUBSTATE_RESET_LEN:
2360
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002361 /* get offset of length field */
2362 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002363
Jack Yu790603c2019-01-28 20:29:31 +08002364 if (length < length_offset) {
2365 android_errorWriteLog(0x534e4554, "122320256");
2366 rw_i93_handle_error(NFC_STATUS_FAILED);
2367 return;
2368 }
2369
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002370 /* set length to zero */
2371 *(p + length_offset) = 0x00;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002372
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002373 if (p_i93->ndef_length > 0) {
2374 /* if 3 bytes length field is needed */
2375 if (p_i93->ndef_length >= 0xFF) {
2376 xx = length_offset + 3;
2377 } else {
2378 xx = length_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002379 }
2380
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002381 /* write the first part of NDEF in the same block */
2382 for (; xx < p_i93->block_size; xx++) {
Jack Yu790603c2019-01-28 20:29:31 +08002383 if (xx > length || p_i93->rw_length > p_i93->ndef_length) {
2384 android_errorWriteLog(0x534e4554, "122320256");
2385 rw_i93_handle_error(NFC_STATUS_FAILED);
2386 return;
2387 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002388 if (p_i93->rw_length < p_i93->ndef_length) {
2389 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2390 } else {
2391 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2392 }
2393 }
2394 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002395
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002396 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2397
George Chang712dcda2020-01-03 20:46:24 +08002398 if (length < p_i93->block_size) {
2399 android_errorWriteLog(0x534e4554, "143109193");
2400 rw_i93_handle_error(NFC_STATUS_FAILED);
2401 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2402 NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002403 /* update next writing offset */
2404 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2405 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2406 } else {
2407 rw_i93_handle_error(NFC_STATUS_FAILED);
2408 }
2409 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002410
2411 case RW_I93_SUBSTATE_WRITE_NDEF:
2412
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002413 /* if it's not the end of tag memory */
2414 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
2415 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002416
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002417 /* if we have more data to write */
2418 if (p_i93->rw_length < p_i93->ndef_length) {
2419 p = p_i93->p_update_data + p_i93->rw_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002420
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002421 p_i93->rw_offset += p_i93->block_size;
2422 p_i93->rw_length += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002423
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002424 /* if this is the last block of NDEF TLV */
2425 if (p_i93->rw_length > p_i93->ndef_length) {
2426 /* length of NDEF TLV in the block */
2427 xx = (uint8_t)(p_i93->block_size -
2428 (p_i93->rw_length - p_i93->ndef_length));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002429
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002430 /* set NULL TLV in the unused part of block */
2431 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2432 memcpy(buff, p, xx);
2433 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002434
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002435 /* if it's the end of tag memory */
2436 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2437 (xx < p_i93->block_size)) {
2438 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002439 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002440
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002441 p_i93->ndef_tlv_last_offset =
2442 p_i93->rw_offset - p_i93->block_size + xx - 1;
2443 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002444
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002445 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2446 NFC_STATUS_OK) {
2447 rw_i93_handle_error(NFC_STATUS_FAILED);
2448 }
2449 } else {
2450 /* if this is the very next block of NDEF TLV */
2451 if (block_number ==
2452 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2453 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002454
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002455 /* write Terminator TLV and NULL TLV */
2456 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2457 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2458 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002459
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002460 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2461 NFC_STATUS_OK) {
2462 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002463 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002464 } else {
2465 /* finished writing NDEF and Terminator TLV */
2466 /* read length field to update length */
2467 block_number =
2468 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2469
2470 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2471 NFC_STATUS_OK) {
2472 /* set offset to length field */
2473 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2474
2475 /* get size of length field */
2476 if (p_i93->ndef_length >= 0xFF) {
2477 p_i93->rw_length = 3;
2478 } else if (p_i93->ndef_length > 0) {
2479 p_i93->rw_length = 1;
2480 } else {
2481 p_i93->rw_length = 0;
2482 }
2483
2484 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2485 } else {
2486 rw_i93_handle_error(NFC_STATUS_FAILED);
2487 }
2488 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002489 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002490 } else {
2491 /* if we have no more data to write */
2492 if (p_i93->rw_length >= p_i93->ndef_length) {
2493 /* finished writing NDEF and Terminator TLV */
2494 /* read length field to update length */
2495 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002496
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002497 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2498 NFC_STATUS_OK) {
2499 /* set offset to length field */
2500 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002501
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002502 /* get size of length field */
2503 if (p_i93->ndef_length >= 0xFF) {
2504 p_i93->rw_length = 3;
2505 } else if (p_i93->ndef_length > 0) {
2506 p_i93->rw_length = 1;
2507 } else {
2508 p_i93->rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002509 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002510
2511 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2512 break;
2513 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002514 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002515 rw_i93_handle_error(NFC_STATUS_FAILED);
2516 }
2517 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002518
2519 case RW_I93_SUBSTATE_UPDATE_LEN:
2520
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002521 /* if we have more length field to write */
2522 if (p_i93->rw_length > 0) {
2523 /* if we got ack for writing, read next block to update rest of length
2524 * field */
2525 if (length == 0) {
2526 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002527
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002528 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2529 NFC_STATUS_OK) {
2530 rw_i93_handle_error(NFC_STATUS_FAILED);
2531 }
2532 } else {
2533 length_offset = p_i93->rw_offset % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002534
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002535 /* update length field within the read block */
2536 for (xx = length_offset; xx < p_i93->block_size; xx++) {
Jack Yu790603c2019-01-28 20:29:31 +08002537 if (xx > length) {
2538 android_errorWriteLog(0x534e4554, "122320256");
2539 rw_i93_handle_error(NFC_STATUS_FAILED);
2540 return;
2541 }
2542
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002543 if (p_i93->rw_length == 3)
2544 *(p + xx) = 0xFF;
2545 else if (p_i93->rw_length == 2)
2546 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2547 else if (p_i93->rw_length == 1)
2548 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002549
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002550 p_i93->rw_length--;
2551 if (p_i93->rw_length == 0) break;
2552 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002553
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002554 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002555
George Chang712dcda2020-01-03 20:46:24 +08002556 if (length < p_i93->block_size) {
2557 android_errorWriteLog(0x534e4554, "143155861");
2558 rw_i93_handle_error(NFC_STATUS_FAILED);
2559 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2560 NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002561 /* set offset to the beginning of next block */
2562 p_i93->rw_offset +=
2563 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2564 } else {
2565 rw_i93_handle_error(NFC_STATUS_FAILED);
2566 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002567 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002568 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002569 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00002570 "%s - NDEF update complete, %d bytes, (%d-%d)", __func__,
2571 p_i93->ndef_length, p_i93->ndef_tlv_start_offset,
2572 p_i93->ndef_tlv_last_offset);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002574 p_i93->state = RW_I93_STATE_IDLE;
2575 p_i93->sent_cmd = 0;
Yi Kong805e3612018-07-25 14:07:29 -07002576 p_i93->p_update_data = nullptr;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002577
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002578 rw_data.status = NFC_STATUS_OK;
2579 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2580 }
2581 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002582
2583 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002584 break;
2585 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002586}
2587
2588/*******************************************************************************
2589**
2590** Function rw_i93_sm_format
2591**
2592** Description Process format procedure
2593**
2594** 1. Get UID
2595** 2. Get sys info for memory size (reset AFI/DSFID)
2596** 3. Get block status to get read-only status
2597** 4. Write CC and empty NDEF
2598**
2599** Returns void
2600**
2601*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002602void rw_i93_sm_format(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002603 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002604 uint8_t flags;
2605 uint16_t length = p_resp->len, xx, block_number;
2606 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2607 tRW_DATA rw_data;
2608 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002609
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002610 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2611 "sub_state:%s (0x%x)",
2612 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002613
Ruchi Kandoibf1b4682019-01-24 15:27:47 -08002614 if (length == 0) {
2615 android_errorWriteLog(0x534e4554, "122323053");
2616 return;
2617 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002618 STREAM_TO_UINT8(flags, p);
2619 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002621 if (flags & I93_FLAG_ERROR_DETECTED) {
2622 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2623 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2624 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2625 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2626 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2627 /* ignore error */
2628 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2629 /* getting system info with protocol extension flag */
Adrian Mocanu476558f2020-02-05 09:37:41 +00002630 /* This STM & ONS tag supports more than 2040 bytes */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002631 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2632 return;
2633 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002634 DLOG_IF(INFO, nfc_debug_enabled)
2635 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002636 rw_i93_handle_error(NFC_STATUS_FAILED);
2637 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002638 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002639 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002640
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002641 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002642 case RW_I93_SUBSTATE_WAIT_UID:
2643
Ruchi Kandoibf1b4682019-01-24 15:27:47 -08002644 if (length < (I93_UID_BYTE_LEN + 1)) {
2645 android_errorWriteLog(0x534e4554, "122323053");
2646 return;
2647 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002648 p++; /* skip DSFID */
2649 p_uid = p_i93->uid;
2650 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002651
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002652 /* get system information to get memory size */
Yi Kong805e3612018-07-25 14:07:29 -07002653 if (rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_NO) ==
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002654 NFC_STATUS_OK) {
2655 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2656 } else {
2657 rw_i93_handle_error(NFC_STATUS_FAILED);
2658 }
2659 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002660
2661 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2662
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002663 p_i93->block_size = 0;
2664 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002665
Ruchi Kandoi451edc92019-01-24 14:45:55 -08002666 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002667 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002668 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002669 }
2670
2671 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2672 /* DSFID, if any DSFID then reset */
2673 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2674 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2675 }
2676 }
2677 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2678 /* AFI, reset to 0 */
2679 if (p_i93->afi != 0x00) {
2680 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2681 }
2682 }
2683
2684 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002685 DLOG_IF(INFO, nfc_debug_enabled)
2686 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002687 rw_i93_handle_error(status);
2688 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2689 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2690 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2691 } else {
2692 rw_i93_handle_error(NFC_STATUS_FAILED);
2693 }
2694 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2695 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2696 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2697 } else {
2698 rw_i93_handle_error(NFC_STATUS_FAILED);
2699 }
2700 } else {
2701 /* get lock status to see if read-only */
2702 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2703 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2704 /* these doesn't support GetMultiBlockSecurityStatus */
2705
2706 rw_cb.tcb.i93.rw_offset = 0;
2707
2708 /* read blocks with option flag to get block security status */
2709 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2710 NFC_STATUS_OK) {
2711 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2712 } else {
2713 rw_i93_handle_error(NFC_STATUS_FAILED);
2714 }
2715 } else {
2716 /* block offset for read-only check */
2717 p_i93->rw_offset = 0;
2718
2719 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2720 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2721 } else {
2722 rw_i93_handle_error(NFC_STATUS_FAILED);
2723 }
2724 }
2725 }
2726
2727 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002728
2729 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2730
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002731 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2732 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2733 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2734 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2735 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002736
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002737 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2738 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2739 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2740 } else {
2741 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002742 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002743 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2744 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2745 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2746 } else {
2747 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002748 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002749 } else {
2750 /* get lock status to see if read-only */
2751 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2752 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2753 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002754
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002755 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002756
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002757 /* read blocks with option flag to get block security status */
2758 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2759 NFC_STATUS_OK) {
2760 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2761 } else {
2762 rw_i93_handle_error(NFC_STATUS_FAILED);
2763 }
2764 } else {
2765 /* block offset for read-only check */
2766 p_i93->rw_offset = 0;
Evan Chu85b7e842013-01-18 11:02:50 -05002767
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002768 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2769 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2770 } else {
2771 rw_i93_handle_error(NFC_STATUS_FAILED);
2772 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002773 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002774 }
2775 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002776
2777 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2778
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002779 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2780 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2781 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2782 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
Jack Yu7cd831f2020-03-18 20:09:14 +08002783 if (length == 0 || ((*p) & I93_BLOCK_LOCKED)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002784 rw_i93_handle_error(NFC_STATUS_FAILED);
2785 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002786 }
2787
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002788 /* if we checked all of user blocks */
2789 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2790 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2791 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2792 /* read the block which has AFI */
2793 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2794 rw_i93_send_cmd_read_single_block(
2795 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002796 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002797 }
2798 } else if (p_i93->rw_offset ==
2799 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2800 /* no block is locked */
2801 } else {
2802 p_i93->rw_offset += p_i93->block_size;
2803 rw_i93_send_cmd_read_single_block(
2804 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2805 break;
2806 }
2807 } else {
2808 /* if any block is locked, we cannot format it */
2809 for (xx = 0; xx < length; xx++) {
2810 if (*(p + xx) & I93_BLOCK_LOCKED) {
2811 rw_i93_handle_error(NFC_STATUS_FAILED);
2812 break;
2813 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002814 }
2815
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002816 /* update block offset for read-only check */
2817 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002818
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002819 /* if need to get more lock status of blocks */
2820 if (p_i93->num_block > p_i93->rw_offset) {
2821 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2822 rw_i93_handle_error(NFC_STATUS_FAILED);
2823 }
2824 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002825 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002826 }
Evan Chu85b7e842013-01-18 11:02:50 -05002827
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002828 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
George Changd8948d42019-10-05 10:59:26 +08002829 /* Block size could be either 4 or 8 or 16 or 32 bytes */
2830 /* Get buffer for the largest block size I93_MAX_BLOCK_LENGH */
2831 p_i93->p_update_data = (uint8_t*)GKI_getbuf(I93_MAX_BLOCK_LENGH);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002832
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002833 if (!p_i93->p_update_data) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002834 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002835 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002836 break;
Alisher Alikhodjaev914f67b2020-07-23 14:38:34 -07002837 } else {
2838 switch (p_i93->block_size) {
2839 case 4:
2840 case 8:
2841 break;
2842 case 16:
2843 case 32: /* initialize unpopulated buffer b/139738828 */
2844 memset(p_i93->p_update_data, I93_ICODE_TLV_TYPE_NULL,
2845 I93_MAX_BLOCK_LENGH);
2846 break;
2847 default:
2848 android_errorWriteLog(0x534e4554, "157650336");
2849 rw_i93_handle_error(NFC_STATUS_FAILED);
2850 return;
2851 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002852 }
2853
2854 p = p_i93->p_update_data;
2855
2856 /* Capability Container */
Raphael Collado867d5c32017-03-27 12:49:40 +02002857 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002858 *(p++) = 0x40; /* version 1.0, read/write */
2859
2860 /* if memory size is less than 2048 bytes */
2861 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2862 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2863 8); /* memory size */
2864 else
2865 *(p++) = 0xFF;
2866
2867 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2868 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2869 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2870 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2871 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2872 else
2873 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2874 supported */
2875 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2876 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2877 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2878 supported */
2879 } else if ((p_i93->product_version ==
2880 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2881 (p_i93->product_version ==
2882 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2883 *(p++) = 0;
2884 } else {
Adrian Mocanu476558f2020-02-05 09:37:41 +00002885 /* STM except LRIS2K, ONS, Broadcom supports read multi block command */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002886
2887 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2888 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2889 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2890 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2891 *(p++) = 0x00;
2892 else
2893 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2894 }
2895
2896 /* zero length NDEF and Terminator TLV */
2897 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2898 *(p++) = 0x00;
2899 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2900 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2901
2902 /* start from block 0 */
2903 p_i93->rw_offset = 0;
2904
2905 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2906 NFC_STATUS_OK) {
2907 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2908 p_i93->rw_offset += p_i93->block_size;
2909 } else {
2910 rw_i93_handle_error(NFC_STATUS_FAILED);
2911 }
2912 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002913
2914 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2915
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002916 /* if we have more data to write */
2917 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2918 block_number = (p_i93->rw_offset / p_i93->block_size);
2919 p = p_i93->p_update_data + p_i93->rw_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002920
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002921 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2922 NFC_STATUS_OK) {
2923 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2924 p_i93->rw_offset += p_i93->block_size;
2925 } else {
2926 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002927 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002928 } else {
2929 GKI_freebuf(p_i93->p_update_data);
Yi Kong805e3612018-07-25 14:07:29 -07002930 p_i93->p_update_data = nullptr;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002931
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002932 p_i93->state = RW_I93_STATE_IDLE;
2933 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002934
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002935 rw_data.status = NFC_STATUS_OK;
2936 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2937 }
2938 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002939
2940 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002941 break;
2942 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002943}
2944
2945/*******************************************************************************
2946**
2947** Function rw_i93_sm_set_read_only
2948**
2949** Description Process read-only procedure
2950**
2951** 1. Update CC as read-only
2952** 2. Lock all block of NDEF TLV
2953** 3. Lock block of CC
2954**
2955** Returns void
2956**
2957*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002958void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2959 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2960 uint8_t flags, block_number;
2961 uint16_t length = p_resp->len;
2962 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2963 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002964
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002965 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2966 "sub_state:%s (0x%x)",
2967 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002968
Jack Yu790603c2019-01-28 20:29:31 +08002969 if (length == 0) {
2970 android_errorWriteLog(0x534e4554, "122322613");
2971 rw_i93_handle_error(NFC_STATUS_FAILED);
2972 return;
2973 }
2974
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002975 STREAM_TO_UINT8(flags, p);
2976 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002977
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002978 if (flags & I93_FLAG_ERROR_DETECTED) {
2979 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2980 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2981 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2982 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2983 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2984 /* ignore error */
2985 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002986 DLOG_IF(INFO, nfc_debug_enabled)
2987 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002988 rw_i93_handle_error(NFC_STATUS_FAILED);
2989 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002990 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002991 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002992
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002993 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002994 case RW_I93_SUBSTATE_WAIT_CC:
2995
George Chang4025e2b2019-08-16 20:37:23 +08002996 if (length < RW_I93_CC_SIZE) {
2997 android_errorWriteLog(0x534e4554, "139188579");
2998 rw_i93_handle_error(NFC_STATUS_FAILED);
2999 return;
3000 }
3001
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003002 /* mark CC as read-only */
3003 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003004
George Chang712dcda2020-01-03 20:46:24 +08003005 if (length < p_i93->block_size) {
3006 android_errorWriteLog(0x534e4554, "143106535");
3007 rw_i93_handle_error(NFC_STATUS_FAILED);
3008 } else if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003009 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
3010 } else {
3011 rw_i93_handle_error(NFC_STATUS_FAILED);
3012 }
3013 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003014
3015 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
3016
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003017 /* successfully write CC then lock all blocks of NDEF TLV */
3018 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
3019 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003020
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003021 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
3022 p_i93->rw_offset += p_i93->block_size;
3023 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
3024 } else {
3025 rw_i93_handle_error(NFC_STATUS_FAILED);
3026 }
3027 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003028
3029 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
3030
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003031 /* if we need to lock more blocks */
3032 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
3033 /* get the next block of NDEF TLV */
3034 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003035
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003036 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
3037 p_i93->rw_offset += p_i93->block_size;
3038 } else {
3039 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003040 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003041 }
3042 /* if the first block of NDEF TLV is different from block of CC */
3043 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
3044 /* lock block of CC */
3045 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
3046 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
3047 } else {
3048 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003049 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003050 } else {
3051 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
3052 p_i93->state = RW_I93_STATE_IDLE;
3053 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003054
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003055 rw_data.status = NFC_STATUS_OK;
3056 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
3057 }
3058 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003059
3060 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
3061
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003062 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
3063 p_i93->state = RW_I93_STATE_IDLE;
3064 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003065
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003066 rw_data.status = NFC_STATUS_OK;
3067 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
3068 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003069
3070 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003071 break;
3072 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003073}
3074
3075/*******************************************************************************
3076**
3077** Function rw_i93_handle_error
3078**
3079** Description notify error to application and clean up
3080**
3081** Returns none
3082**
3083*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003084void rw_i93_handle_error(tNFC_STATUS status) {
3085 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3086 tRW_DATA rw_data;
3087 tRW_EVENT event;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003088
George Changff05f952021-03-15 05:51:51 +00003089 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
3090 "%s - status:0x%02X, state:0x%X", __func__, status, p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003091
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003092 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003093
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003094 if (rw_cb.p_cback) {
3095 rw_data.status = status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003096
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003097 switch (p_i93->state) {
3098 case RW_I93_STATE_IDLE: /* in case of RawFrame */
3099 event = RW_I93_INTF_ERROR_EVT;
3100 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003101
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003102 case RW_I93_STATE_BUSY:
3103 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
3104 /* There is no response to Stay Quiet command */
3105 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
3106 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
3107 rw_data.i93_cmd_cmpl.error_code = 0;
3108 event = RW_I93_CMD_CMPL_EVT;
3109 } else {
3110 event = RW_I93_INTF_ERROR_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003111 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003112 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003113
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003114 case RW_I93_STATE_DETECT_NDEF:
Love Khanna57a3dfa2017-03-28 20:03:38 +05303115 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003116 rw_data.ndef.cur_size = 0;
3117 rw_data.ndef.max_size = 0;
3118 rw_data.ndef.flags = 0;
3119 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
3120 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
3121 event = RW_I93_NDEF_DETECT_EVT;
3122 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003124 case RW_I93_STATE_READ_NDEF:
3125 event = RW_I93_NDEF_READ_FAIL_EVT;
3126 break;
3127
3128 case RW_I93_STATE_UPDATE_NDEF:
Yi Kong805e3612018-07-25 14:07:29 -07003129 p_i93->p_update_data = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003130 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
3131 break;
3132
3133 case RW_I93_STATE_FORMAT:
3134 if (p_i93->p_update_data) {
3135 GKI_freebuf(p_i93->p_update_data);
Yi Kong805e3612018-07-25 14:07:29 -07003136 p_i93->p_update_data = nullptr;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003137 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003138 event = RW_I93_FORMAT_CPLT_EVT;
3139 break;
3140
3141 case RW_I93_STATE_SET_READ_ONLY:
3142 event = RW_I93_SET_TAG_RO_EVT;
3143 break;
3144
3145 case RW_I93_STATE_PRESENCE_CHECK:
3146 event = RW_I93_PRESENCE_CHECK_EVT;
3147 break;
3148
3149 default:
3150 event = RW_I93_MAX_EVT;
3151 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003152 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003153
3154 p_i93->state = RW_I93_STATE_IDLE;
3155 p_i93->sent_cmd = 0;
3156
3157 if (event != RW_I93_MAX_EVT) {
3158 (*(rw_cb.p_cback))(event, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003159 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003160 } else {
3161 p_i93->state = RW_I93_STATE_IDLE;
3162 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003163}
3164
3165/*******************************************************************************
3166**
3167** Function rw_i93_process_timeout
3168**
3169** Description process timeout event
3170**
3171** Returns none
3172**
3173*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003174void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
3175 NFC_HDR* p_buf;
Evan Chu85b7e842013-01-18 11:02:50 -05003176
George Changff05f952021-03-15 05:51:51 +00003177 DLOG_IF(INFO, nfc_debug_enabled)
3178 << StringPrintf("%s - event=%d", __func__, p_tle->event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003179
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003180 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
3181 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
3182 (rw_cb.tcb.i93.p_retry_cmd) &&
3183 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
3184 rw_cb.tcb.i93.retry_count++;
George Changff05f952021-03-15 05:51:51 +00003185 LOG(ERROR) << StringPrintf("%s - retry_count = %d", __func__,
3186 rw_cb.tcb.i93.retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05003187
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003188 p_buf = rw_cb.tcb.i93.p_retry_cmd;
Yi Kong805e3612018-07-25 14:07:29 -07003189 rw_cb.tcb.i93.p_retry_cmd = nullptr;
Evan Chu7c69b272013-05-14 12:48:36 -04003190
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003191 if (rw_i93_send_to_lower(p_buf)) {
3192 return;
3193 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003194 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003195
3196 /* all retrial is done or failed to send command to lower layer */
3197 if (rw_cb.tcb.i93.p_retry_cmd) {
3198 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
Yi Kong805e3612018-07-25 14:07:29 -07003199 rw_cb.tcb.i93.p_retry_cmd = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003200 rw_cb.tcb.i93.retry_count = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003201 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003202 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
3203 } else {
George Changff05f952021-03-15 05:51:51 +00003204 LOG(ERROR) << StringPrintf("%s - unknown event=%d", __func__, p_tle->event);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003205 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003206}
3207
3208/*******************************************************************************
3209**
3210** Function rw_i93_data_cback
3211**
3212** Description This callback function receives the data from NFCC.
3213**
3214** Returns none
3215**
3216*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07003217static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
3218 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003219 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3220 NFC_HDR* p_resp;
3221 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003222
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003223 uint8_t begin_state = p_i93->state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003224
George Changff05f952021-03-15 05:51:51 +00003225 DLOG_IF(INFO, nfc_debug_enabled)
3226 << StringPrintf("%s - event = 0x%X", __func__, event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003227
Love Khanna57a3dfa2017-03-28 20:03:38 +05303228 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
3229 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003230 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003231
Jizhou Liao499be102017-08-11 12:57:12 -07003232 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003233 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
3234 p_i93->retry_count++;
Evan Chu85b7e842013-01-18 11:02:50 -05003235
George Changff05f952021-03-15 05:51:51 +00003236 LOG(ERROR) << StringPrintf("%s - retry_count = %d", __func__,
3237 p_i93->retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05003238
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003239 p_resp = p_i93->p_retry_cmd;
Yi Kong805e3612018-07-25 14:07:29 -07003240 p_i93->p_retry_cmd = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003241 if (rw_i93_send_to_lower(p_resp)) {
Jack Yu80e31a52019-01-28 22:10:26 +08003242 if (event == NFC_DATA_CEVT) {
3243 p_resp = (NFC_HDR*)p_data->data.p_data;
3244 GKI_freebuf(p_resp);
3245 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003246 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003247 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003248 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003249
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003250 /* all retrial is done or failed to send command to lower layer */
3251 if (p_i93->p_retry_cmd) {
3252 GKI_freebuf(p_i93->p_retry_cmd);
Yi Kong805e3612018-07-25 14:07:29 -07003253 p_i93->p_retry_cmd = nullptr;
Evan Chu85b7e842013-01-18 11:02:50 -05003254 p_i93->retry_count = 0;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003255 }
3256
3257 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
3258 } else {
3259 /* free retry buffer */
3260 if (p_i93->p_retry_cmd) {
3261 GKI_freebuf(p_i93->p_retry_cmd);
Yi Kong805e3612018-07-25 14:07:29 -07003262 p_i93->p_retry_cmd = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003263 p_i93->retry_count = 0;
3264 }
Yi Kong805e3612018-07-25 14:07:29 -07003265 NFC_SetStaticRfCback(nullptr);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003266 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
Evan Chu85b7e842013-01-18 11:02:50 -05003267 }
Jack Yu80e31a52019-01-28 22:10:26 +08003268 if ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK)) {
3269 p_resp = (NFC_HDR*)p_data->data.p_data;
3270 GKI_freebuf(p_resp);
3271 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003272 return;
3273 }
3274
3275 if (event != NFC_DATA_CEVT) {
3276 return;
3277 }
3278
3279 p_resp = (NFC_HDR*)p_data->data.p_data;
3280
3281 nfc_stop_quick_timer(&p_i93->timer);
3282
3283 /* free retry buffer */
3284 if (p_i93->p_retry_cmd) {
3285 GKI_freebuf(p_i93->p_retry_cmd);
Yi Kong805e3612018-07-25 14:07:29 -07003286 p_i93->p_retry_cmd = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003287 p_i93->retry_count = 0;
3288 }
Evan Chu85b7e842013-01-18 11:02:50 -05003289
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003290 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00003291 "%s - RW I93 state: <%s (%d)>", __func__,
3292 rw_i93_get_state_name(p_i93->state).c_str(), p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003293
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003294 switch (p_i93->state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003295 case RW_I93_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003296 /* Unexpected Response from VICC, it should be raw frame response */
3297 /* forward to upper layer without parsing */
3298 p_i93->sent_cmd = 0;
3299 if (rw_cb.p_cback) {
3300 rw_data.raw_frame.status = p_data->data.status;
3301 rw_data.raw_frame.p_data = p_resp;
3302 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
Yi Kong805e3612018-07-25 14:07:29 -07003303 p_resp = nullptr;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003304 } else {
3305 GKI_freebuf(p_resp);
3306 }
3307 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003308 case RW_I93_STATE_BUSY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003309 p_i93->state = RW_I93_STATE_IDLE;
3310 rw_i93_send_to_upper(p_resp);
3311 GKI_freebuf(p_resp);
3312 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003313
3314 case RW_I93_STATE_DETECT_NDEF:
George Changff05f952021-03-15 05:51:51 +00003315 if (p_i93->i93_t5t_mode == RW_I93_GET_SYS_INFO_MEM_INFO) {
3316 DLOG_IF(INFO, nfc_debug_enabled)
3317 << StringPrintf("%s - rw_i93_sm_detect_ndef()", __func__);
3318 rw_i93_sm_detect_ndef(p_resp);
3319 } else {
3320 DLOG_IF(INFO, nfc_debug_enabled)
3321 << StringPrintf("%s - rw_t5t_sm_detect_ndef()", __func__);
3322 rw_t5t_sm_detect_ndef(p_resp);
3323 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003324 GKI_freebuf(p_resp);
3325 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003326
3327 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003328 rw_i93_sm_read_ndef(p_resp);
3329 /* p_resp may send upper lyaer */
3330 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003331
3332 case RW_I93_STATE_UPDATE_NDEF:
George Changff05f952021-03-15 05:51:51 +00003333 if (p_i93->i93_t5t_mode == RW_I93_GET_SYS_INFO_MEM_INFO) {
3334 DLOG_IF(INFO, nfc_debug_enabled)
3335 << StringPrintf("%s - rw_i93_sm_update_ndef()", __func__);
3336 rw_i93_sm_update_ndef(p_resp);
3337 } else {
3338 DLOG_IF(INFO, nfc_debug_enabled)
3339 << StringPrintf("%s - rw_t5t_sm_update_ndef()", __func__);
3340 rw_t5t_sm_update_ndef(p_resp);
3341 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003342 GKI_freebuf(p_resp);
3343 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003344
3345 case RW_I93_STATE_FORMAT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003346 rw_i93_sm_format(p_resp);
3347 GKI_freebuf(p_resp);
3348 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003349
3350 case RW_I93_STATE_SET_READ_ONLY:
George Changff05f952021-03-15 05:51:51 +00003351 if (p_i93->i93_t5t_mode == RW_I93_GET_SYS_INFO_MEM_INFO) {
3352 DLOG_IF(INFO, nfc_debug_enabled)
3353 << StringPrintf("%s - rw_i93_sm_set_read_only()", __func__);
3354 rw_i93_sm_set_read_only(p_resp);
3355 } else {
3356 DLOG_IF(INFO, nfc_debug_enabled)
3357 << StringPrintf("%s - rw_t5t_sm_set_read_only()", __func__);
3358 rw_t5t_sm_set_read_only(p_resp);
3359 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003360 GKI_freebuf(p_resp);
3361 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003362
3363 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003364 p_i93->state = RW_I93_STATE_IDLE;
3365 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003366
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003367 /* if any response, send presence check with ok */
3368 rw_data.status = NFC_STATUS_OK;
3369 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3370 GKI_freebuf(p_resp);
3371 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003372
3373 default:
George Changff05f952021-03-15 05:51:51 +00003374 LOG(ERROR) << StringPrintf("%s - invalid state=%d", __func__,
3375 p_i93->state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003376 GKI_freebuf(p_resp);
3377 break;
3378 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003379
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003380 if (begin_state != p_i93->state) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003381 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00003382 << StringPrintf("%s - RW I93 state changed:<%s> -> <%s>", __func__,
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003383 rw_i93_get_state_name(begin_state).c_str(),
3384 rw_i93_get_state_name(p_i93->state).c_str());
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003385 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003386}
3387
3388/*******************************************************************************
3389**
3390** Function rw_i93_select
3391**
Love Khanna57a3dfa2017-03-28 20:03:38 +05303392** Description Initialise ISO 15693 / T5T RW
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003393**
3394** Returns NFC_STATUS_OK if success
3395**
3396*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003397tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
3398 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3399 uint8_t uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003400
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003401 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003402
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003403 NFC_SetStaticRfCback(rw_i93_data_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003404
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003405 p_i93->state = RW_I93_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003406
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003407 /* convert UID to big endian format - MSB(0xE0) in first byte */
3408 p = uid;
3409 STREAM_TO_ARRAY8(p, p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003410
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003411 rw_i93_get_product_version(uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003412
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003413 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003414}
3415
3416/*******************************************************************************
3417**
3418** Function RW_I93Inventory
3419**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003420** Description This function send Inventory command with/without AFI
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003421** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3422**
3423** RW_I93_RESPONSE_EVT will be returned
3424**
3425** Returns NFC_STATUS_OK if success
3426** NFC_STATUS_NO_BUFFERS if out of buffer
3427** NFC_STATUS_BUSY if busy
3428** NFC_STATUS_FAILED if other error
3429**
3430*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003431tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3432 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003433
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003434 DLOG_IF(INFO, nfc_debug_enabled)
3435 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003436
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003437 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003438 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3439 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003440 return NFC_STATUS_BUSY;
3441 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003442
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003443 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003444
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003445 if (status == NFC_STATUS_OK) {
3446 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3447 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003448
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003449 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003450}
3451
3452/*******************************************************************************
3453**
3454** Function RW_I93StayQuiet
3455**
3456** Description This function send Inventory command
3457**
3458** RW_I93_CMD_CMPL_EVT will be returned
3459**
3460** Returns NFC_STATUS_OK if success
3461** NFC_STATUS_NO_BUFFERS if out of buffer
3462** NFC_STATUS_BUSY if busy
3463** NFC_STATUS_FAILED if other error
3464**
3465*******************************************************************************/
Arach MOHAMMED BRAHIM559c7d42020-10-09 14:24:20 +02003466tNFC_STATUS RW_I93StayQuiet(uint8_t* p_uid) {
3467 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003468
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003469 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003470
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003471 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Arach MOHAMMED BRAHIM559c7d42020-10-09 14:24:20 +02003472 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
3473 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003474 return NFC_STATUS_BUSY;
3475 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003476
Arach MOHAMMED BRAHIM559c7d42020-10-09 14:24:20 +02003477 if (p_uid) {
3478 status = rw_i93_send_cmd_stay_quiet(p_uid);
3479 if (status == NFC_STATUS_OK) {
3480 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3481 rw_cb.tcb.i93.addr_mode = RW_I93_MODE_ADDRESSED;
3482 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003483 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003484
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003485 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003486}
3487
3488/*******************************************************************************
3489**
3490** Function RW_I93ReadSingleBlock
3491**
3492** Description This function send Read Single Block command
3493**
3494** RW_I93_RESPONSE_EVT will be returned
3495**
3496** Returns NFC_STATUS_OK if success
3497** NFC_STATUS_NO_BUFFERS if out of buffer
3498** NFC_STATUS_BUSY if busy
3499** NFC_STATUS_FAILED if other error
3500**
3501*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003502tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3503 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003504
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003505 DLOG_IF(INFO, nfc_debug_enabled)
George Changff05f952021-03-15 05:51:51 +00003506 << StringPrintf("%s - block_number:0x%02X", __func__, block_number);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003507
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003508 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003509 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3510 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003511 return NFC_STATUS_BUSY;
3512 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003513
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003514 status = rw_i93_send_cmd_read_single_block(block_number, false);
3515 if (status == NFC_STATUS_OK) {
3516 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3517 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003518
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003519 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003520}
3521
3522/*******************************************************************************
3523**
3524** Function RW_I93WriteSingleBlock
3525**
3526** Description This function send Write Single Block command
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003527** Application must get block size first by calling
3528** RW_I93GetSysInfo().
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003529**
3530** RW_I93_CMD_CMPL_EVT will be returned
3531**
3532** Returns NFC_STATUS_OK if success
3533** NFC_STATUS_NO_BUFFERS if out of buffer
3534** NFC_STATUS_BUSY if busy
3535** NFC_STATUS_FAILED if other error
3536**
3537*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003538tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3539 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003540
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003541 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003542
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003543 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003544 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3545 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003546 return NFC_STATUS_BUSY;
3547 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003548
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003549 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003550 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003551 return NFC_STATUS_FAILED;
3552 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003553
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003554 status = rw_i93_send_cmd_write_single_block(block_number, p_data);
3555 if (status == NFC_STATUS_OK) {
3556 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3557 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003558
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003559 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003560}
3561
3562/*******************************************************************************
3563**
3564** Function RW_I93LockBlock
3565**
3566** Description This function send Lock Block command
3567**
3568** RW_I93_CMD_CMPL_EVT will be returned
3569**
3570** Returns NFC_STATUS_OK if success
3571** NFC_STATUS_NO_BUFFERS if out of buffer
3572** NFC_STATUS_BUSY if busy
3573** NFC_STATUS_FAILED if other error
3574**
3575*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003576tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3577 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003578
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003579 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003580
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003581 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003582 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3583 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003584 return NFC_STATUS_BUSY;
3585 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003586
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003587 status = rw_i93_send_cmd_lock_block(block_number);
3588 if (status == NFC_STATUS_OK) {
3589 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3590 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003591
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003592 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003593}
3594
3595/*******************************************************************************
3596**
3597** Function RW_I93ReadMultipleBlocks
3598**
3599** Description This function send Read Multiple Blocks command
3600**
3601** RW_I93_RESPONSE_EVT will be returned
3602**
3603** Returns NFC_STATUS_OK if success
3604** NFC_STATUS_NO_BUFFERS if out of buffer
3605** NFC_STATUS_BUSY if busy
3606** NFC_STATUS_FAILED if other error
3607**
3608*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003609tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3610 uint16_t number_blocks) {
3611 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003612
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003613 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003614
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003615 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003616 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3617 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003618 return NFC_STATUS_BUSY;
3619 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003621 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3622 if (status == NFC_STATUS_OK) {
3623 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3624 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003625
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003626 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003627}
3628
3629/*******************************************************************************
3630**
3631** Function RW_I93WriteMultipleBlocks
3632**
3633** Description This function send Write Multiple Blocks command
3634**
3635** RW_I93_CMD_CMPL_EVT will be returned
3636**
3637** Returns NFC_STATUS_OK if success
3638** NFC_STATUS_NO_BUFFERS if out of buffer
3639** NFC_STATUS_BUSY if busy
3640** NFC_STATUS_FAILED if other error
3641**
3642*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02003643tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003644 uint16_t number_blocks, uint8_t* p_data) {
3645 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003646
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003647 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003648
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003649 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003650 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3651 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003652 return NFC_STATUS_BUSY;
3653 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003654
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003655 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003656 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003657 return NFC_STATUS_FAILED;
3658 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003659
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003660 status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
3661 p_data);
3662 if (status == NFC_STATUS_OK) {
3663 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3664 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003665
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003666 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003667}
3668
3669/*******************************************************************************
3670**
3671** Function RW_I93Select
3672**
3673** Description This function send Select command
3674**
3675** UID[0]: 0xE0, MSB
3676** UID[1]: IC Mfg Code
3677** ...
3678** UID[7]: LSB
3679**
3680** RW_I93_CMD_CMPL_EVT will be returned
3681**
3682** Returns NFC_STATUS_OK if success
3683** NFC_STATUS_NO_BUFFERS if out of buffer
3684** NFC_STATUS_BUSY if busy
3685** NFC_STATUS_FAILED if other error
3686**
3687*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003688tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3689 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003690
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003691 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003692
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003693 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01003694 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
3695 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003696 return NFC_STATUS_BUSY;
3697 }
3698
3699 if (p_uid) {
3700 status = rw_i93_send_cmd_select(p_uid);
3701 if (status == NFC_STATUS_OK) {
3702 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01003703 rw_cb.tcb.i93.addr_mode = RW_I93_MODE_NON_ADDRESSED;
3704 rw_cb.tcb.i93.intl_flags |= RW_I93_FLAG_SELECTED_STATE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003705 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003706 } else {
Arach MOHAMMED BRAHIM8147f482020-10-26 18:15:31 +01003707 LOG(ERROR) << StringPrintf("%s - UID shall be provided", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003708 status = NFC_STATUS_FAILED;
3709 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003710
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003711 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003712}
3713
3714/*******************************************************************************
3715**
3716** Function RW_I93ResetToReady
3717**
3718** Description This function send Reset To Ready command
3719**
3720** RW_I93_CMD_CMPL_EVT will be returned
3721**
3722** Returns NFC_STATUS_OK if success
3723** NFC_STATUS_NO_BUFFERS if out of buffer
3724** NFC_STATUS_BUSY if busy
3725** NFC_STATUS_FAILED if other error
3726**
3727*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003728tNFC_STATUS RW_I93ResetToReady(void) {
3729 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003730
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003731 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003732
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003733 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00003734 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
3735 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003736 return NFC_STATUS_BUSY;
3737 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003738
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003739 status = rw_i93_send_cmd_reset_to_ready();
3740 if (status == NFC_STATUS_OK) {
3741 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3742 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003743
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003744 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003745}
3746
3747/*******************************************************************************
3748**
3749** Function RW_I93WriteAFI
3750**
3751** Description This function send Write AFI command
3752**
3753** RW_I93_CMD_CMPL_EVT will be returned
3754**
3755** Returns NFC_STATUS_OK if success
3756** NFC_STATUS_NO_BUFFERS if out of buffer
3757** NFC_STATUS_BUSY if busy
3758** NFC_STATUS_FAILED if other error
3759**
3760*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003761tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3762 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003763
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003764 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003765
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003766 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003767 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3768 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003769 return NFC_STATUS_BUSY;
3770 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003771
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003772 status = rw_i93_send_cmd_write_afi(afi);
3773 if (status == NFC_STATUS_OK) {
3774 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3775 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003776
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003777 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003778}
3779
3780/*******************************************************************************
3781**
3782** Function RW_I93LockAFI
3783**
3784** Description This function send Lock AFI command
3785**
3786** RW_I93_CMD_CMPL_EVT will be returned
3787**
3788** Returns NFC_STATUS_OK if success
3789** NFC_STATUS_NO_BUFFERS if out of buffer
3790** NFC_STATUS_BUSY if busy
3791** NFC_STATUS_FAILED if other error
3792**
3793*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003794tNFC_STATUS RW_I93LockAFI(void) {
3795 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003796
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003797 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003798
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003799 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003800 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3801 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003802 return NFC_STATUS_BUSY;
3803 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003804
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003805 status = rw_i93_send_cmd_lock_afi();
3806 if (status == NFC_STATUS_OK) {
3807 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3808 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003809
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003810 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003811}
3812
3813/*******************************************************************************
3814**
3815** Function RW_I93WriteDSFID
3816**
3817** Description This function send Write DSFID command
3818**
3819** RW_I93_CMD_CMPL_EVT will be returned
3820**
3821** Returns NFC_STATUS_OK if success
3822** NFC_STATUS_NO_BUFFERS if out of buffer
3823** NFC_STATUS_BUSY if busy
3824** NFC_STATUS_FAILED if other error
3825**
3826*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003827tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3828 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003829
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003830 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003831
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003832 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003833 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3834 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003835 return NFC_STATUS_BUSY;
3836 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003837
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003838 status = rw_i93_send_cmd_write_dsfid(dsfid);
3839 if (status == NFC_STATUS_OK) {
3840 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3841 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003842
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003843 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003844}
3845
3846/*******************************************************************************
3847**
3848** Function RW_I93LockDSFID
3849**
3850** Description This function send Lock DSFID command
3851**
3852** RW_I93_CMD_CMPL_EVT will be returned
3853**
3854** Returns NFC_STATUS_OK if success
3855** NFC_STATUS_NO_BUFFERS if out of buffer
3856** NFC_STATUS_BUSY if busy
3857** NFC_STATUS_FAILED if other error
3858**
3859*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003860tNFC_STATUS RW_I93LockDSFID(void) {
3861 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003862
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003863 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003864
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003865 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003866 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3867 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003868 return NFC_STATUS_BUSY;
3869 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003870
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003871 status = rw_i93_send_cmd_lock_dsfid();
3872 if (status == NFC_STATUS_OK) {
3873 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3874 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003875
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003876 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003877}
3878
3879/*******************************************************************************
3880**
3881** Function RW_I93GetSysInfo
3882**
3883** Description This function send Get System Information command
3884**
3885** RW_I93_RESPONSE_EVT will be returned
3886**
3887** Returns NFC_STATUS_OK if success
3888** NFC_STATUS_NO_BUFFERS if out of buffer
3889** NFC_STATUS_BUSY if busy
3890** NFC_STATUS_FAILED if other error
3891**
3892*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003893tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3894 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003895
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003896 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003897
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003898 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00003899 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
3900 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003901 return NFC_STATUS_BUSY;
3902 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003903
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003904 if (p_uid) {
3905 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3906 } else {
Yi Kong805e3612018-07-25 14:07:29 -07003907 status = rw_i93_send_cmd_get_sys_info(nullptr, I93_FLAG_PROT_EXT_NO);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003908 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003909
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003910 if (status == NFC_STATUS_OK) {
3911 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3912 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003913
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003914 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003915}
3916
3917/*******************************************************************************
3918**
3919** Function RW_I93GetMultiBlockSecurityStatus
3920**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003921** Description This function send Get Multiple Block Security Status
3922** command
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003923**
3924** RW_I93_RESPONSE_EVT will be returned
3925**
3926** Returns NFC_STATUS_OK if success
3927** NFC_STATUS_NO_BUFFERS if out of buffer
3928** NFC_STATUS_BUSY if busy
3929** NFC_STATUS_FAILED if other error
3930**
3931*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003932tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3933 uint16_t number_blocks) {
3934 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003935
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003936 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003937
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003938 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003939 LOG(ERROR) << StringPrintf(
3940 "Unable to start command at state "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003941 "(0x%X)",
3942 rw_cb.tcb.i93.state);
3943 return NFC_STATUS_BUSY;
3944 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003945
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003946 status =
3947 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3948 if (status == NFC_STATUS_OK) {
3949 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3950 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003952 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003953}
3954
3955/*******************************************************************************
3956**
3957** Function RW_I93DetectNDef
3958**
3959** Description This function performs NDEF detection procedure
3960**
3961** RW_I93_NDEF_DETECT_EVT will be returned
3962**
3963** Returns NFC_STATUS_OK if success
3964** NFC_STATUS_FAILED if busy or other error
3965**
3966*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003967tNFC_STATUS RW_I93DetectNDef(void) {
3968 tNFC_STATUS status;
3969 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003970
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003971 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003972
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003973 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00003974 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
3975 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003976 return NFC_STATUS_FAILED;
3977 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003978
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003979 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
Yi Kong805e3612018-07-25 14:07:29 -07003980 status = rw_i93_send_cmd_inventory(nullptr, false, 0x00);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003981 sub_state = RW_I93_SUBSTATE_WAIT_UID;
Arach MOHAMMED BRAHIMe05a0972020-10-09 17:06:56 +02003982
3983 } else if (((rw_cb.tcb.i93.num_block == 0) ||
3984 (rw_cb.tcb.i93.block_size == 0)) &&
3985 (!appl_dta_mode_flag)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003986 status =
3987 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3988 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003989
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003990 /* clear all flags */
3991 rw_cb.tcb.i93.intl_flags = 0;
3992 } else {
3993 /* read CC in the first block */
3994 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3995 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3996 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003997
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003998 if (status == NFC_STATUS_OK) {
3999 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
4000 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05004001
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004002 /* clear flags except flag for 2 bytes of number of blocks */
4003 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
4004 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004005
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004006 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004007}
4008
4009/*******************************************************************************
4010**
4011** Function RW_I93ReadNDef
4012**
4013** Description This function performs NDEF read procedure
4014** Note: RW_I93DetectNDef () must be called before using this
4015**
4016** The following event will be returned
4017** RW_I93_NDEF_READ_EVT for each segmented NDEF message
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08004018** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
4019** complete NDEF
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004020** RW_I93_NDEF_READ_FAIL_EVT for failure
4021**
4022** Returns NFC_STATUS_OK if success
4023** NFC_STATUS_FAILED if I93 is busy or other error
4024**
4025*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004026tNFC_STATUS RW_I93ReadNDef(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004027 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004028
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004029 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00004030 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
4031 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004032 return NFC_STATUS_FAILED;
4033 }
4034
4035 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
4036 (rw_cb.tcb.i93.ndef_length > 0)) {
4037 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
4038 rw_cb.tcb.i93.rw_length = 0;
4039
4040 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
4041 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
4042 } else {
4043 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004044 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004045 } else {
George Changff05f952021-03-15 05:51:51 +00004046 LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004047 return NFC_STATUS_FAILED;
4048 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004049
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004050 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004051}
4052
4053/*******************************************************************************
4054**
4055** Function RW_I93UpdateNDef
4056**
4057** Description This function performs NDEF update procedure
4058** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08004059** Updating data must not be removed until returning
4060** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004061**
4062** The following event will be returned
4063** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
4064** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
4065**
4066** Returns NFC_STATUS_OK if success
4067** NFC_STATUS_FAILED if I93 is busy or other error
4068**
4069*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004070tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
4071 uint16_t block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004072
George Changff05f952021-03-15 05:51:51 +00004073 DLOG_IF(INFO, nfc_debug_enabled)
4074 << StringPrintf("%s - length:%d", __func__, length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004075
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004076 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00004077 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
4078 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004079 return NFC_STATUS_FAILED;
4080 }
4081
4082 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
4083 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
George Changff05f952021-03-15 05:51:51 +00004084 LOG(ERROR) << StringPrintf("%s - NDEF is read-only", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004085 return NFC_STATUS_FAILED;
4086 }
4087 if (rw_cb.tcb.i93.max_ndef_length < length) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004088 LOG(ERROR) << StringPrintf(
George Changff05f952021-03-15 05:51:51 +00004089 "%s - data (%d bytes) is more than max NDEF length "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004090 "(%d)",
George Changff05f952021-03-15 05:51:51 +00004091 __func__, length, rw_cb.tcb.i93.max_ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004092 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004093 }
4094
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004095 rw_cb.tcb.i93.ndef_length = length;
4096 rw_cb.tcb.i93.p_update_data = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004097
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004098 /* read length field */
4099 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
4100 rw_cb.tcb.i93.rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004101
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004102 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004103
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004104 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
4105 NFC_STATUS_OK) {
4106 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
4107 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
4108 } else {
4109 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004110 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004111 } else {
George Changff05f952021-03-15 05:51:51 +00004112 LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004113 return NFC_STATUS_FAILED;
4114 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004115
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004116 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004117}
4118
4119/*******************************************************************************
4120**
4121** Function RW_I93FormatNDef
4122**
4123** Description This function performs formatting procedure
4124**
4125** RW_I93_FORMAT_CPLT_EVT will be returned
4126**
4127** Returns NFC_STATUS_OK if success
4128** NFC_STATUS_FAILED if busy or other error
4129**
4130*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004131tNFC_STATUS RW_I93FormatNDef(void) {
4132 tNFC_STATUS status;
4133 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004134
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004135 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004136
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004137 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004138 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
4139 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004140 return NFC_STATUS_FAILED;
4141 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004142
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004143 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
4144 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
4145 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
4146 */
4147 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004149 /* read blocks with option flag to get block security status */
4150 status = rw_i93_send_cmd_read_single_block(0x0000, true);
4151 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
4152 } else {
4153 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
4154 sub_state = RW_I93_SUBSTATE_WAIT_UID;
4155 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004156
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004157 if (status == NFC_STATUS_OK) {
4158 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
4159 rw_cb.tcb.i93.sub_state = sub_state;
4160 rw_cb.tcb.i93.intl_flags = 0;
4161 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004162
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004163 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004164}
4165
4166/*******************************************************************************
4167**
4168** Function RW_I93SetTagReadOnly
4169**
4170** Description This function performs NDEF read-only procedure
4171** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08004172** Updating data must not be removed until returning
4173** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004174**
4175** The RW_I93_SET_TAG_RO_EVT event will be returned.
4176**
4177** Returns NFC_STATUS_OK if success
4178** NFC_STATUS_FAILED if I93 is busy or other error
4179**
4180*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004181tNFC_STATUS RW_I93SetTagReadOnly(void) {
George Changff05f952021-03-15 05:51:51 +00004182 uint8_t cc_blk0[4];
4183
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004184 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004185
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004186 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
George Changff05f952021-03-15 05:51:51 +00004187 LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
4188 __func__, rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004189 return NFC_STATUS_FAILED;
4190 }
4191
George Changff05f952021-03-15 05:51:51 +00004192 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
4193 (rw_cb.tcb.i93.i93_t5t_mode != RW_T5T_CC_READ_MEM_INFO)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004194 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
George Changff05f952021-03-15 05:51:51 +00004195 LOG(ERROR) << StringPrintf("%s - NDEF is already read-only", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004196 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004197 }
4198
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004199 /* get CC in the first block */
4200 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
4201 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4202 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
4203 } else {
4204 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004205 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004206 } else {
George Changff05f952021-03-15 05:51:51 +00004207 if (rw_cb.tcb.i93.i93_t5t_mode == RW_T5T_CC_READ_MEM_INFO) {
4208 memcpy(cc_blk0, rw_cb.tcb.i93.gre_cc_content, 4);
4209
4210 /* mark CC as read-only */
4211 *(cc_blk0 + 1) |= I93_ICODE_CC_READ_ONLY;
4212
4213 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
4214 "%s - Set CC1 to RO - cc[0]=0x%02x, cc[1]=0x%02x, "
4215 "cc[2]=0x%02x, cc[3]=0x%02x",
4216 __func__, *cc_blk0, *(cc_blk0 + 1), *(cc_blk0 + 2), *(cc_blk0 + 3));
4217
4218 if (rw_i93_send_cmd_write_single_block(0, cc_blk0) == NFC_STATUS_OK) {
4219 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4220 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
4221 } else {
4222 rw_i93_handle_error(NFC_STATUS_FAILED);
4223 return NFC_STATUS_FAILED;
4224 }
4225
4226 return NFC_STATUS_OK;
4227 }
4228 LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004229 return NFC_STATUS_FAILED;
4230 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004231
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004232 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004233}
4234
4235/*****************************************************************************
4236**
4237** Function RW_I93PresenceCheck
4238**
4239** Description Check if the tag is still in the field.
4240**
4241** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
4242** presence or non-presence.
4243**
4244** Returns NFC_STATUS_OK, if raw data frame sent
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08004245** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
4246** operation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004247** NFC_STATUS_FAILED: other error
4248**
4249*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004250tNFC_STATUS RW_I93PresenceCheck(void) {
4251 tNFC_STATUS status;
4252 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004253
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07004254 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004255
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004256 if (!rw_cb.p_cback) {
4257 return NFC_STATUS_FAILED;
4258 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
4259 evt_data.status = NFC_STATUS_FAILED;
George Changff05f952021-03-15 05:51:51 +00004260 (*rw_cb.p_cback)(RW_I93_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004261
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004262 return NFC_STATUS_OK;
4263 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
4264 return NFC_STATUS_BUSY;
4265 } else {
George Changff05f952021-03-15 05:51:51 +00004266 if (rw_cb.tcb.i93.i93_t5t_mode == RW_I93_GET_SYS_INFO_MEM_INFO) {
4267 /* The support of AFI by the VICC is optional, so do not include AFI */
4268 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
4269 } else {
4270 /* Extended command not expected for presence check */
4271 rw_cb.tcb.i93.intl_flags &= ~RW_I93_FLAG_EXT_COMMANDS;
4272 status = rw_i93_send_cmd_read_single_block(0, false);
4273 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004274
4275 if (status == NFC_STATUS_OK) {
4276 /* do not retry during presence check */
4277 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
4278 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004279 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004280 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004281
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004282 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004283}
4284
Arach MOHAMMED BRAHIM15b9ff92021-01-14 17:20:51 +01004285/*****************************************************************************
4286**
4287** Function RW_I93SetAddressingMode
4288**
4289** Description Set if the tag must be addressed with UID or not.
4290**
4291** The addressing mode (addressed or non-addressed) must be
4292** done at the module initialization prior to the Tag
4293** activation.
4294**
4295** Returns NFC_STATUS_OK, if mode is stored
4296** NFC_STATUS_FAILED: other error
4297**
4298*****************************************************************************/
4299tNFC_STATUS RW_I93SetAddressingMode(bool mode) {
4300 DLOG_IF(INFO, nfc_debug_enabled)
4301 << StringPrintf("%s - I93 state:%d", __func__, rw_cb.tcb.i93.state);
4302
4303 if (rw_cb.tcb.i93.state == RW_I93_STATE_IDLE) {
4304 DLOG_IF(INFO, nfc_debug_enabled)
4305 << StringPrintf("%s - mode:%d", __func__, mode);
4306 if (mode) {
4307 rw_cb.tcb.i93.addr_mode = RW_I93_MODE_ADDRESSED;
4308 } else {
4309 rw_cb.tcb.i93.addr_mode = RW_I93_MODE_NON_ADDRESSED;
4310 }
4311 return NFC_STATUS_OK;
4312 } else {
4313 return NFC_STATUS_FAILED;
4314 }
4315}
4316
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004317/*******************************************************************************
4318**
4319** Function rw_i93_get_state_name
4320**
4321** Description This function returns the state name.
4322**
4323** NOTE conditionally compiled to save memory.
4324**
4325** Returns pointer to the name
4326**
4327*******************************************************************************/
George Changff05f952021-03-15 05:51:51 +00004328std::string rw_i93_get_state_name(uint8_t state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004329 switch (state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004330 case RW_I93_STATE_NOT_ACTIVATED:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004331 return "NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004332 case RW_I93_STATE_IDLE:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004333 return "IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004334 case RW_I93_STATE_BUSY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004335 return "BUSY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004336 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004337 return "NDEF_DETECTION";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004338 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004339 return "READ_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004340 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004341 return "UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004342 case RW_I93_STATE_FORMAT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004343 return "FORMAT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004344 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004345 return "SET_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004346 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004347 return "PRESENCE_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004348 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004349 return "???? UNKNOWN STATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004350 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004351}
4352
4353/*******************************************************************************
4354**
4355** Function rw_i93_get_sub_state_name
4356**
4357** Description This function returns the sub_state name.
4358**
4359** NOTE conditionally compiled to save memory.
4360**
4361** Returns pointer to the name
4362**
4363*******************************************************************************/
George Changff05f952021-03-15 05:51:51 +00004364std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004365 switch (sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004366 case RW_I93_SUBSTATE_WAIT_UID:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004367 return "WAIT_UID";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004368 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004369 return "WAIT_SYS_INFO";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004370 case RW_I93_SUBSTATE_WAIT_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004371 return "WAIT_CC";
George Changff05f952021-03-15 05:51:51 +00004372 case RW_I93_SUBSTATE_WAIT_CC_EXT:
4373 return "WAIT_CC_EXT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004374 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004375 return "SEARCH_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004376 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004377 return "CHECK_LOCK_STATUS";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004378 case RW_I93_SUBSTATE_RESET_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004379 return "RESET_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004380 case RW_I93_SUBSTATE_WRITE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004381 return "WRITE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004382 case RW_I93_SUBSTATE_UPDATE_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004383 return "UPDATE_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004384 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004385 return "WAIT_RESET_DSFID_AFI";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004386 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004387 return "CHECK_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004388 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004389 return "WRITE_CC_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004390 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004391 return "WAIT_UPDATE_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004392 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004393 return "LOCK_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004394 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004395 return "WAIT_LOCK_CC";
George Changff05f952021-03-15 05:51:51 +00004396 case RW_I93_SUBSTATE_LOCK_T5T_AREA:
4397 return "LOCK_T5T_AREA";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004398 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004399 return "???? UNKNOWN SUBSTATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004400 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004401}
Evan Chu85b7e842013-01-18 11:02:50 -05004402
4403/*******************************************************************************
4404**
4405** Function rw_i93_get_tag_name
4406**
4407** Description This function returns the tag name.
4408**
4409** NOTE conditionally compiled to save memory.
4410**
4411** Returns pointer to the name
4412**
4413*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004414static std::string rw_i93_get_tag_name(uint8_t product_version) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004415 switch (product_version) {
Evan Chu85b7e842013-01-18 11:02:50 -05004416 case RW_I93_ICODE_SLI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004417 return "SLI/SLIX";
Evan Chu85b7e842013-01-18 11:02:50 -05004418 case RW_I93_ICODE_SLI_S:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004419 return "SLI-S/SLIX-S";
Evan Chu85b7e842013-01-18 11:02:50 -05004420 case RW_I93_ICODE_SLI_L:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004421 return "SLI-L/SLIX-L";
Evan Chu85b7e842013-01-18 11:02:50 -05004422 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004423 return "Tag-it HF-I Plus Inlay";
Evan Chu85b7e842013-01-18 11:02:50 -05004424 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004425 return "Tag-it HF-I Plus Chip";
Evan Chu85b7e842013-01-18 11:02:50 -05004426 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004427 return "Tag-it HF-I Standard Chip/Inlyas";
Evan Chu85b7e842013-01-18 11:02:50 -05004428 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004429 return "Tag-it HF-I Pro Chip/Inlays";
Evan Chu85b7e842013-01-18 11:02:50 -05004430 case RW_I93_STM_LRI1K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004431 return "LRi1K";
Evan Chu85b7e842013-01-18 11:02:50 -05004432 case RW_I93_STM_LRI2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004433 return "LRi2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004434 case RW_I93_STM_LRIS2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004435 return "LRiS2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004436 case RW_I93_STM_LRIS64K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004437 return "LRiS64K";
Evan Chu85b7e842013-01-18 11:02:50 -05004438 case RW_I93_STM_M24LR64_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004439 return "M24LR64";
Evan Chu85b7e842013-01-18 11:02:50 -05004440 case RW_I93_STM_M24LR04E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004441 return "M24LR04E";
Evan Chu85b7e842013-01-18 11:02:50 -05004442 case RW_I93_STM_M24LR16E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004443 return "M24LR16E";
Olivier Lorente487e6d12021-04-27 16:13:23 +02004444 case RW_I93_STM_M24LR16D_W:
4445 return "M24LR16D-W";
Evan Chu85b7e842013-01-18 11:02:50 -05004446 case RW_I93_STM_M24LR64E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004447 return "M24LR64E";
Raphael Collado867d5c32017-03-27 12:49:40 +02004448 case RW_I93_STM_ST25DV04K:
4449 return "ST25DV04";
4450 case RW_I93_STM_ST25DVHIK:
4451 return "ST25DV";
Adrian Mocanu476558f2020-02-05 09:37:41 +00004452 case RW_I93_ONS_N36RW02:
4453 return ("N36RW02");
4454 case RW_I93_ONS_N24RF04:
4455 return ("N24RF04");
4456 case RW_I93_ONS_N24RF04E:
4457 return ("N24RF04E");
4458 case RW_I93_ONS_N24RF16:
4459 return ("N24RF16");
4460 case RW_I93_ONS_N24RF16E:
4461 return ("N24RF16E");
4462 case RW_I93_ONS_N24RF64:
4463 return ("N24RF64");
4464 case RW_I93_ONS_N24RF64E:
4465 return ("N24RF64E");
Evan Chu85b7e842013-01-18 11:02:50 -05004466 case RW_I93_UNKNOWN_PRODUCT:
4467 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004468 return "UNKNOWN";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004469 }
Alisher Alikhodjaev24a570b2020-06-18 15:44:19 -07004470}