blob: e5c55519c0577531b596be4aa1ba2248df9e950b [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 ******************************************************************************/
25#include <string.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080026#include "bt_types.h"
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080027#include "nfc_target.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080028#include "trace_api.h"
29
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080030#include "nfc_api.h"
31#include "nfc_int.h"
32#include "rw_api.h"
33#include "rw_int.h"
34
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080035/* Response timeout */
36#define RW_I93_TOUT_RESP 1000
37/* stay quiet timeout */
38#define RW_I93_TOUT_STAY_QUIET 200
39/* max reading data if read multi block is supported */
40#define RW_I93_READ_MULTI_BLOCK_SIZE 128
41/* CC, zero length NDEF, Terminator TLV */
42#define RW_I93_FORMAT_DATA_LEN 8
43/* max getting lock status if get multi block sec is supported */
44#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080045
46/* main state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080047enum {
48 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
49 RW_I93_STATE_IDLE, /* waiting for upper layer API */
50 RW_I93_STATE_BUSY, /* waiting for response from tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080051
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080052 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
53 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
54 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
55 RW_I93_STATE_FORMAT, /* performing format procedure */
56 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080057
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080058 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080059};
60
61/* sub state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080062enum {
63 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
64 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
65 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
66 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
67 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080068
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080069 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
70 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
71 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080072
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080073 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
74 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
75 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
76 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080078 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
79 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
80 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080081};
82
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070083static std::string rw_i93_get_state_name(uint8_t state);
84static std::string rw_i93_get_sub_state_name(uint8_t sub_state);
85static std::string rw_i93_get_tag_name(uint8_t product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080087static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
88 tNFC_CONN* p_data);
89void rw_i93_handle_error(tNFC_STATUS status);
90tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
Raphael Collado867d5c32017-03-27 12:49:40 +020091tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080092
93/*******************************************************************************
94**
95** Function rw_i93_get_product_version
96**
97** Description Get product version from UID
98**
99** Returns void
100**
101*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800102void rw_i93_get_product_version(uint8_t* p_uid) {
103 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800104
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800105 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
106 return;
107 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800108
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700109 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800110
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800111 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800112
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800113 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
114 if (p_uid[2] == I93_UID_ICODE_SLI)
115 p_i93->product_version = RW_I93_ICODE_SLI;
116 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
117 p_i93->product_version = RW_I93_ICODE_SLI_S;
118 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
119 p_i93->product_version = RW_I93_ICODE_SLI_L;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800120 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800121 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
122 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
123 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
124 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
125 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
126 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
127 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
128 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
129 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
130 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
131 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
132 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
133 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
134 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
135 else
136 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
137 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
138 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
139 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
140 p_i93->product_version = RW_I93_STM_M24LR04E_R;
141 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
142 p_i93->product_version = RW_I93_STM_M24LR16E_R;
143 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
144 p_i93->product_version = RW_I93_STM_M24LR64E_R;
Raphael Collado867d5c32017-03-27 12:49:40 +0200145 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DVHIK)
146 p_i93->product_version = RW_I93_STM_ST25DVHIK;
147 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DV04K)
148 p_i93->product_version = RW_I93_STM_ST25DV04K;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800149 else {
150 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
151 case I93_IC_REF_STM_LRI1K:
152 p_i93->product_version = RW_I93_STM_LRI1K;
153 break;
154 case I93_IC_REF_STM_LRI2K:
155 p_i93->product_version = RW_I93_STM_LRI2K;
156 break;
157 case I93_IC_REF_STM_LRIS2K:
158 p_i93->product_version = RW_I93_STM_LRIS2K;
159 break;
160 case I93_IC_REF_STM_LRIS64K:
161 p_i93->product_version = RW_I93_STM_LRIS64K;
162 break;
163 case I93_IC_REF_STM_M24LR64_R:
164 p_i93->product_version = RW_I93_STM_M24LR64_R;
165 break;
166 default:
167 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
168 break;
169 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800170 }
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*******************************************************************************/
202bool rw_i93_process_ext_sys_info(uint8_t* p_data) {
203 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
209 STREAM_TO_UINT8(p_i93->info_flags, p);
210
211 p_uid = uid;
212 STREAM_TO_ARRAY8(p_uid, p);
213
214 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
215 STREAM_TO_UINT8(p_i93->dsfid, p);
216 }
217 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
218 STREAM_TO_UINT8(p_i93->afi, p);
219 }
220 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
221 STREAM_TO_UINT16(p_i93->num_block, p);
222
223 /* it is one less than actual number of bytes */
224 p_i93->num_block += 1;
225
226 STREAM_TO_UINT8(p_i93->block_size, p);
227 /* it is one less than actual number of blocks */
228 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
229 }
230 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
231 STREAM_TO_UINT8(p_i93->ic_reference, p);
232
233 /* clear existing UID to set product version */
234 p_i93->uid[0] = 0x00;
235
236 /* store UID and get product version */
237 rw_i93_get_product_version(p_uid);
238
239 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
240 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
241 /* STM supports more than 2040 bytes */
242 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
243 }
244 }
245 }
246 return true;
247}
248
249/*******************************************************************************
250**
Evan Chu85b7e842013-01-18 11:02:50 -0500251** Function rw_i93_process_sys_info
252**
253** Description Store system information of tag
254**
255** Returns FALSE if retrying with protocol extension flag
256**
257*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800258bool rw_i93_process_sys_info(uint8_t* p_data) {
259 uint8_t* p = p_data;
260 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
261 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -0500262
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700263 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500264
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800265 STREAM_TO_UINT8(p_i93->info_flags, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500266
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800267 p_uid = uid;
268 STREAM_TO_ARRAY8(p_uid, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500269
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800270 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
271 STREAM_TO_UINT8(p_i93->dsfid, p);
272 }
273 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
274 STREAM_TO_UINT8(p_i93->afi, p);
275 }
276 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
277 if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
278 STREAM_TO_UINT16(p_i93->num_block, p);
279 } else {
280 STREAM_TO_UINT8(p_i93->num_block, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500281 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800282 /* it is one less than actual number of bytes */
283 p_i93->num_block += 1;
Evan Chu85b7e842013-01-18 11:02:50 -0500284
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800285 STREAM_TO_UINT8(p_i93->block_size, p);
286 /* it is one less than actual number of blocks */
287 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
288 }
289 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
290 STREAM_TO_UINT8(p_i93->ic_reference, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500291
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800292 /* clear existing UID to set product version */
293 p_i93->uid[0] = 0x00;
Evan Chu85b7e842013-01-18 11:02:50 -0500294
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800295 /* store UID and get product version */
296 rw_i93_get_product_version(p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -0500297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800298 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
299 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
300 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
301 p_i93->num_block = 8;
302 p_i93->block_size = 4;
303 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
304 /*
305 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
306 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
307 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
308 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
309 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
310 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
311 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
312 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
313 */
314 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
315 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
316 /*
317 ** M24LR16E-R or M24LR64E-R returns system information
318 ** without memory size, if option flag is not set.
319 ** LRIS64K and M24LR64-R return error if option flag is not
320 ** set.
321 */
322 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
323 /* get memory size with protocol extension flag */
324 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
325 NFC_STATUS_OK) {
326 /* STM supports more than 2040 bytes */
327 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
328
329 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500330 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800331 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800332 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
333 (p_i93->ic_reference == 0x21)) {
334 /* workaround of byte order in memory size information */
335 p_i93->num_block = 64;
336 p_i93->block_size = 4;
Raphael Collado867d5c32017-03-27 12:49:40 +0200337 } else if (!(p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)) {
338 if (!(p_i93->intl_flags & RW_I93_FLAG_EXT_COMMANDS)) {
339 if (rw_i93_send_cmd_get_ext_sys_info(NULL) == NFC_STATUS_OK) {
340 /* STM supports more than 2040 bytes */
341 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
342
343 return false;
344 }
345 }
Evan Chu85b7e842013-01-18 11:02:50 -0500346 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800347 }
Evan Chu85b7e842013-01-18 11:02:50 -0500348 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800349 }
Evan Chu85b7e842013-01-18 11:02:50 -0500350
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800351 return true;
Evan Chu85b7e842013-01-18 11:02:50 -0500352}
353
354/*******************************************************************************
355**
356** Function rw_i93_check_sys_info_prot_ext
357**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800358** Description Check if need to set protocol extension flag to get system
359** info
Evan Chu85b7e842013-01-18 11:02:50 -0500360**
361** Returns TRUE if sent Get System Info with protocol extension flag
362**
363*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800364bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
365 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -0500366
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700367 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500368
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800369 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
370 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
371 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
372 (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
373 NFC_STATUS_OK)) {
374 return true;
375 } else {
376 return false;
377 }
Evan Chu85b7e842013-01-18 11:02:50 -0500378}
379
380/*******************************************************************************
381**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800382** Function rw_i93_send_to_upper
383**
384** Description Send response to upper layer
385**
386** Returns void
387**
388*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800389void rw_i93_send_to_upper(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700390 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800391 uint16_t length = p_resp->len;
392 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
393 tRW_DATA rw_data;
394 uint8_t event = RW_I93_MAX_EVT;
395 uint8_t flags;
396 NFC_HDR* p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800397
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700398 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800399
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800400 STREAM_TO_UINT8(flags, p);
401 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800402
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800403 if (flags & I93_FLAG_ERROR_DETECTED) {
404 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
405 /* getting system info with protocol extension flag */
406 /* This STM tag supports more than 2040 bytes */
407 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
408 p_i93->state = RW_I93_STATE_BUSY;
409 } else {
410 /* notify error to upper layer */
411 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
412 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
413 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800414
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800415 rw_cb.tcb.i93.sent_cmd = 0;
416 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800417 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800418 return;
419 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800420
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800421 switch (p_i93->sent_cmd) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800422 case I93_CMD_INVENTORY:
423
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800424 /* forward inventory response */
425 rw_data.i93_inventory.status = NFC_STATUS_OK;
426 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800427
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800428 p_uid = rw_data.i93_inventory.uid;
429 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800430
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800431 /* store UID and get product version */
432 rw_i93_get_product_version(p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800433
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800434 event = RW_I93_INVENTORY_EVT;
435 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800436
437 case I93_CMD_READ_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200438 case I93_CMD_EXT_READ_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800439 case I93_CMD_READ_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200440 case I93_CMD_EXT_READ_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800441 case I93_CMD_GET_MULTI_BLK_SEC:
Raphael Collado867d5c32017-03-27 12:49:40 +0200442 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800443
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800444 /* forward tag data or security status */
445 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800446
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800447 if (p_buff) {
448 p_buff->offset = 0;
449 p_buff->len = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800450
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800451 memcpy((p_buff + 1), p, length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800452
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800453 rw_data.i93_data.status = NFC_STATUS_OK;
454 rw_data.i93_data.command = p_i93->sent_cmd;
455 rw_data.i93_data.p_data = p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800456
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800457 event = RW_I93_DATA_EVT;
458 } else {
459 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
460 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
461 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800462
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800463 event = RW_I93_CMD_CMPL_EVT;
464 }
465 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800466
467 case I93_CMD_WRITE_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200468 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800469 case I93_CMD_LOCK_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200470 case I93_CMD_EXT_LOCK_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800471 case I93_CMD_WRITE_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200472 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800473 case I93_CMD_SELECT:
474 case I93_CMD_RESET_TO_READY:
475 case I93_CMD_WRITE_AFI:
476 case I93_CMD_LOCK_AFI:
477 case I93_CMD_WRITE_DSFID:
478 case I93_CMD_LOCK_DSFID:
479
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800480 /* notify the complete of command */
481 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
482 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
483 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800484
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800485 event = RW_I93_CMD_CMPL_EVT;
486 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800487
488 case I93_CMD_GET_SYS_INFO:
489
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800490 if (rw_i93_process_sys_info(p)) {
491 rw_data.i93_sys_info.status = NFC_STATUS_OK;
492 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
493 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
494 rw_data.i93_sys_info.afi = p_i93->afi;
495 rw_data.i93_sys_info.num_block = p_i93->num_block;
496 rw_data.i93_sys_info.block_size = p_i93->block_size;
497 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
Evan Chu85b7e842013-01-18 11:02:50 -0500498
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800499 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
Evan Chu85b7e842013-01-18 11:02:50 -0500500
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800501 event = RW_I93_SYS_INFO_EVT;
502 } else {
503 /* retrying with protocol extension flag */
504 p_i93->state = RW_I93_STATE_BUSY;
505 return;
506 }
507 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800508
Raphael Collado867d5c32017-03-27 12:49:40 +0200509 case I93_CMD_EXT_GET_SYS_INFO:
510
511 if (rw_i93_process_ext_sys_info(p)) {
512 rw_data.i93_sys_info.status = NFC_STATUS_OK;
513 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
514 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
515 rw_data.i93_sys_info.afi = p_i93->afi;
516 rw_data.i93_sys_info.num_block = p_i93->num_block;
517 rw_data.i93_sys_info.block_size = p_i93->block_size;
518 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
519
520 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
521
522 event = RW_I93_SYS_INFO_EVT;
523 } else {
524 /* retrying with protocol extension flag or with extended sys info
525 * command */
526 p_i93->state = RW_I93_STATE_BUSY;
527 return;
528 }
529 break;
530
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800531 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800532 break;
533 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800534
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800535 rw_cb.tcb.i93.sent_cmd = 0;
536 if (event != RW_I93_MAX_EVT) {
537 (*(rw_cb.p_cback))(event, &rw_data);
538 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700539 LOG(ERROR) << StringPrintf("Invalid response");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800540 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800541}
542
543/*******************************************************************************
544**
545** Function rw_i93_send_to_lower
546**
547** Description Send Request frame to lower layer
548**
549** Returns TRUE if success
550**
551*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800552bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800553 /* store command for retransmitting */
554 if (rw_cb.tcb.i93.p_retry_cmd) {
555 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
556 rw_cb.tcb.i93.p_retry_cmd = NULL;
557 }
Evan Chu85b7e842013-01-18 11:02:50 -0500558
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800559 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
Evan Chu85b7e842013-01-18 11:02:50 -0500560
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800561 if (rw_cb.tcb.i93.p_retry_cmd) {
562 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
563 sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
564 }
Evan Chu85b7e842013-01-18 11:02:50 -0500565
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800566 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700567 LOG(ERROR) << StringPrintf("failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800568 return false;
569 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800570
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800571 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
572 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800574 return true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800575}
576
577/*******************************************************************************
578**
579** Function rw_i93_send_cmd_inventory
580**
581** Description Send Inventory Request to VICC
582**
583** Returns tNFC_STATUS
584**
585*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800586tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
587 uint8_t afi) {
588 NFC_HDR* p_cmd;
589 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800590
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700591 DLOG_IF(INFO, nfc_debug_enabled)
592 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800593
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800594 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800595
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800596 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700597 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800598 return NFC_STATUS_NO_BUFFERS;
599 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800601 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
602 p_cmd->len = 3;
603 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800604
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800605 /* Flags */
606 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
607 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
608 if (including_afi) {
609 flags |= I93_FLAG_AFI_PRESENT;
610 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700611
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800612 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800614 /* Command Code */
615 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800617 if (including_afi) {
618 /* Parameters */
619 UINT8_TO_STREAM(p, afi); /* Optional AFI */
620 p_cmd->len++;
621 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700622
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800623 if (p_uid) {
624 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
625 ARRAY8_TO_STREAM(p, p_uid); /* UID */
626 p_cmd->len += I93_UID_BYTE_LEN;
627 } else {
628 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
629 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800630
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800631 if (rw_i93_send_to_lower(p_cmd)) {
632 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
633 return NFC_STATUS_OK;
634 } else {
635 return NFC_STATUS_FAILED;
636 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800637}
638
639/*******************************************************************************
640**
641** Function rw_i93_send_cmd_stay_quiet
642**
643** Description Send Stay Quiet Request to VICC
644**
645** Returns tNFC_STATUS
646**
647*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800648tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
649 NFC_HDR* p_cmd;
650 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800651
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700652 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800653
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800654 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800655
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800656 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700657 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800658 return NFC_STATUS_NO_BUFFERS;
659 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800660
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800661 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
662 p_cmd->len = 10;
663 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800664
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800665 /* Flags */
666 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
667 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800668
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800669 /* Command Code */
670 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800672 /* Parameters */
673 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800674
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800675 if (rw_i93_send_to_lower(p_cmd)) {
676 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800678 /* restart timer for stay quiet */
679 nfc_start_quick_timer(
680 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
681 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
682 return NFC_STATUS_OK;
683 } else {
684 return NFC_STATUS_FAILED;
685 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800686}
687
688/*******************************************************************************
689**
690** Function rw_i93_send_cmd_read_single_block
691**
692** Description Send Read Single Block Request to VICC
693**
694** Returns tNFC_STATUS
695**
696*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800697tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
698 bool read_security) {
699 NFC_HDR* p_cmd;
700 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800701
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700702 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800703
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800704 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800705
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800706 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700707 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800708 return NFC_STATUS_NO_BUFFERS;
709 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800710
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800711 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
712 p_cmd->len = 11;
713 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800714
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800715 /* Flags */
716 flags =
717 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500718
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800719 if (read_security) flags |= I93_FLAG_OPTION_SET;
Evan Chu85b7e842013-01-18 11:02:50 -0500720
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800721 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
722 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500723
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800724 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800725
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800726 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200727 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
728 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_SINGLE_BLOCK);
729 } else {
730 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
731 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800732
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800733 /* Parameters */
734 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500735
Raphael Collado867d5c32017-03-27 12:49:40 +0200736 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
737 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800738 UINT16_TO_STREAM(p, block_number); /* Block number */
739 p_cmd->len++;
740 } else {
741 UINT8_TO_STREAM(p, block_number); /* Block number */
742 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800743
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800744 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200745 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
746 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_SINGLE_BLOCK;
747 else
748 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800749 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_write_single_block
758**
759** Description Send Write Single Block Request to VICC
760**
761** Returns tNFC_STATUS
762**
763*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800764tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
765 uint8_t* p_data) {
766 NFC_HDR* p_cmd;
767 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800768
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700769 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800771 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800772
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800773 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700774 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800775 return NFC_STATUS_NO_BUFFERS;
776 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800777
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800778 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
779 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
780 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800782 /* Flags */
783 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
784 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
785 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
786 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
787 /* Option must be set for TI tag */
788 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
789 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
790 } else {
791 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
792 RW_I93_FLAG_DATA_RATE);
793 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800794
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800795 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
796 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500797
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800798 UINT8_TO_STREAM(p, flags);
Evan Chu85b7e842013-01-18 11:02:50 -0500799
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800800 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200801 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
802 UINT8_TO_STREAM(p, I93_CMD_EXT_WRITE_SINGLE_BLOCK);
803 } else {
804 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
805 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800806
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800807 /* Parameters */
808 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500809
Raphael Collado867d5c32017-03-27 12:49:40 +0200810 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
811 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800812 UINT16_TO_STREAM(p, block_number); /* Block number */
813 p_cmd->len++;
814 } else {
815 UINT8_TO_STREAM(p, block_number); /* Block number */
816 }
Evan Chu85b7e842013-01-18 11:02:50 -0500817
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800818 /* Data */
819 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800820
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800821 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200822 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
823 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_SINGLE_BLOCK;
824 else
825 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800826 return NFC_STATUS_OK;
827 } else {
828 return NFC_STATUS_FAILED;
829 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800830}
831
832/*******************************************************************************
833**
834** Function rw_i93_send_cmd_lock_block
835**
836** Description Send Lock Block Request to VICC
837**
Evan Chu85b7e842013-01-18 11:02:50 -0500838** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
839** do not support.
840**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800841** Returns tNFC_STATUS
842**
843*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800844tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
845 NFC_HDR* p_cmd;
846 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800847
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700848 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800849
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800850 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800851
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800852 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700853 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800854 return NFC_STATUS_NO_BUFFERS;
855 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800856
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800857 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
858 p_cmd->len = 11;
859 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800860
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800861 /* Flags */
862 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
863 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
864 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
865 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
866 /* Option must be set for TI tag */
867 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
868 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
869 } else {
870 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
871 RW_I93_FLAG_DATA_RATE));
872 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800873
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800874 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200875 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
876 UINT8_TO_STREAM(p, I93_CMD_EXT_LOCK_BLOCK);
877 } else {
878 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
879 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800880
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800881 /* Parameters */
882 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +0200883
884 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
885 UINT16_TO_STREAM(p, block_number); /* Block number */
886 p_cmd->len++;
887 } else {
888 UINT8_TO_STREAM(p, block_number); /* Block number */
889 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800890
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800891 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200892 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
893 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_LOCK_BLOCK;
894 else
895 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800896 return NFC_STATUS_OK;
897 } else {
898 return NFC_STATUS_FAILED;
899 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800900}
901
902/*******************************************************************************
903**
904** Function rw_i93_send_cmd_read_multi_blocks
905**
906** Description Send Read Multiple Blocks Request to VICC
907**
908** Returns tNFC_STATUS
909**
910*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800911tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
912 uint16_t number_blocks) {
913 NFC_HDR* p_cmd;
914 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800915
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700916 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800917
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800918 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800919
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800920 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700921 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800922 return NFC_STATUS_NO_BUFFERS;
923 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800924
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800925 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
926 p_cmd->len = 12;
927 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800928
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800929 /* Flags */
930 flags =
931 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500932
Raphael Collado867d5c32017-03-27 12:49:40 +0200933 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800934 flags |= I93_FLAG_PROT_EXT_YES;
Raphael Collado867d5c32017-03-27 12:49:40 +0200935 }
Evan Chu85b7e842013-01-18 11:02:50 -0500936
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800937 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800938
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800939 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200940 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
941 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_MULTI_BLOCK);
942 } else {
943 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
944 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800945
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800946 /* Parameters */
947 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500948
Raphael Collado867d5c32017-03-27 12:49:40 +0200949 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
950 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800951 UINT16_TO_STREAM(p, first_block_number); /* First block number */
952 p_cmd->len++;
953 } else {
954 UINT8_TO_STREAM(p, first_block_number); /* First block number */
955 }
Evan Chu85b7e842013-01-18 11:02:50 -0500956
Raphael Collado867d5c32017-03-27 12:49:40 +0200957 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
958 UINT16_TO_STREAM(
959 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
960 p_cmd->len++;
961 } else {
962 UINT8_TO_STREAM(
963 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
964 }
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_READ_MULTI_BLOCK;
969 else
970 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_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_write_multi_blocks
980**
981** Description Send Write Multiple Blocks Request to VICC
982**
983** Returns tNFC_STATUS
984**
985*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +0200986tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800987 uint16_t number_blocks,
988 uint8_t* p_data) {
989 NFC_HDR* p_cmd;
990 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800991
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700992 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800993
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800994 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800995
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800996 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700997 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800998 return NFC_STATUS_NO_BUFFERS;
999 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001000
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001001 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1002 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
1003 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001004
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001005 /* Flags */
1006 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1007 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001008
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001009 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001010 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1011 INT8_TO_STREAM(p, I93_CMD_EXT_WRITE_MULTI_BLOCK);
1012 } else {
1013 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
1014 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001015
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001016 /* Parameters */
1017 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +02001018 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1019 UINT16_TO_STREAM(p, first_block_number); /* Block number */
1020 UINT16_TO_STREAM(
1021 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1022 p_cmd->len += 2;
1023 } else {
1024 UINT8_TO_STREAM(p, first_block_number); /* Block number */
1025 UINT8_TO_STREAM(
1026 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1027 }
1028
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001029 UINT8_TO_STREAM(
1030 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001031
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001032 /* Data */
1033 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001034
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001035 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001036 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1037 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_MULTI_BLOCK;
1038 else
1039 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001040 return NFC_STATUS_OK;
1041 } else {
1042 return NFC_STATUS_FAILED;
1043 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001044}
1045
1046/*******************************************************************************
1047**
1048** Function rw_i93_send_cmd_select
1049**
1050** Description Send Select Request to VICC
1051**
1052** Returns tNFC_STATUS
1053**
1054*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001055tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1056 NFC_HDR* p_cmd;
1057 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001058
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001059 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001060
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001061 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001062
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001063 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001064 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001065 return NFC_STATUS_NO_BUFFERS;
1066 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001067
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001068 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1069 p_cmd->len = 10;
1070 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001071
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001072 /* Flags */
1073 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1074 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001075
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001076 /* Command Code */
1077 UINT8_TO_STREAM(p, I93_CMD_SELECT);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001078
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001079 /* Parameters */
1080 ARRAY8_TO_STREAM(p, p_uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001081
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001082 if (rw_i93_send_to_lower(p_cmd)) {
1083 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1084 return NFC_STATUS_OK;
1085 } else {
1086 return NFC_STATUS_FAILED;
1087 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001088}
1089
1090/*******************************************************************************
1091**
1092** Function rw_i93_send_cmd_reset_to_ready
1093**
1094** Description Send Reset to Ready Request to VICC
1095**
1096** Returns tNFC_STATUS
1097**
1098*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001099tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1100 NFC_HDR* p_cmd;
1101 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001102
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001103 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001104
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001105 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001106
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001107 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001108 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001109 return NFC_STATUS_NO_BUFFERS;
1110 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001111
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001112 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1113 p_cmd->len = 10;
1114 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001115
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001116 /* Flags */
1117 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1118 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001119
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001120 /* Command Code */
1121 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001122
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001123 /* Parameters */
1124 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001125
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001126 if (rw_i93_send_to_lower(p_cmd)) {
1127 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1128 return NFC_STATUS_OK;
1129 } else {
1130 return NFC_STATUS_FAILED;
1131 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001132}
1133
1134/*******************************************************************************
1135**
1136** Function rw_i93_send_cmd_write_afi
1137**
1138** Description Send Write AFI Request to VICC
1139**
1140** Returns tNFC_STATUS
1141**
1142*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001143tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1144 NFC_HDR* p_cmd;
1145 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001146
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001147 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001149 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001150
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001151 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001152 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001153 return NFC_STATUS_NO_BUFFERS;
1154 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001155
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001156 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1157 p_cmd->len = 11;
1158 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001159
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001160 /* Flags */
1161 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1162 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001163
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001164 /* Command Code */
1165 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001166
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001167 /* Parameters */
1168 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1169 UINT8_TO_STREAM(p, afi); /* AFI */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001170
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001171 if (rw_i93_send_to_lower(p_cmd)) {
1172 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1173 return NFC_STATUS_OK;
1174 } else {
1175 return NFC_STATUS_FAILED;
1176 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001177}
1178
1179/*******************************************************************************
1180**
1181** Function rw_i93_send_cmd_lock_afi
1182**
1183** Description Send Lock AFI Request to VICC
1184**
1185** Returns tNFC_STATUS
1186**
1187*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001188tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1189 NFC_HDR* p_cmd;
1190 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001192 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001193
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001194 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001195
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001196 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001197 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001198 return NFC_STATUS_NO_BUFFERS;
1199 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001201 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1202 p_cmd->len = 10;
1203 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001204
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001205 /* Flags */
1206 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1207 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001208
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001209 /* Command Code */
1210 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001211
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001212 /* Parameters */
1213 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
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)) {
1216 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1217 return NFC_STATUS_OK;
1218 } else {
1219 return NFC_STATUS_FAILED;
1220 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001221}
1222
1223/*******************************************************************************
1224**
1225** Function rw_i93_send_cmd_write_dsfid
1226**
1227** Description Send Write DSFID Request to VICC
1228**
1229** Returns tNFC_STATUS
1230**
1231*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001232tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1233 NFC_HDR* p_cmd;
1234 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001235
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001236 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001237
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001238 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001239
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001240 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001241 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001242 return NFC_STATUS_NO_BUFFERS;
1243 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001244
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001245 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1246 p_cmd->len = 11;
1247 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001248
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001249 /* Flags */
1250 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1251 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001252
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001253 /* Command Code */
1254 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001255
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001256 /* Parameters */
1257 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1258 UINT8_TO_STREAM(p, dsfid); /* DSFID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001260 if (rw_i93_send_to_lower(p_cmd)) {
1261 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1262 return NFC_STATUS_OK;
1263 } else {
1264 return NFC_STATUS_FAILED;
1265 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001266}
1267
1268/*******************************************************************************
1269**
1270** Function rw_i93_send_cmd_lock_dsfid
1271**
1272** Description Send Lock DSFID Request to VICC
1273**
1274** Returns tNFC_STATUS
1275**
1276*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001277tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1278 NFC_HDR* p_cmd;
1279 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001280
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001281 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001282
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001283 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001284
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001285 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001286 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001287 return NFC_STATUS_NO_BUFFERS;
1288 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001289
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001290 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1291 p_cmd->len = 10;
1292 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001293
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001294 /* Flags */
1295 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1296 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001297
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001298 /* Command Code */
1299 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001300
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001301 /* Parameters */
1302 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001304 if (rw_i93_send_to_lower(p_cmd)) {
1305 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1306 return NFC_STATUS_OK;
1307 } else {
1308 return NFC_STATUS_FAILED;
1309 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001310}
1311
1312/*******************************************************************************
1313**
Raphael Collado867d5c32017-03-27 12:49:40 +02001314** Function rw_i93_send_cmd_get_ext_sys_info
1315**
1316** Description Send Get Extended System Information Request to VICC
1317**
1318** Returns tNFC_STATUS
1319**
1320*******************************************************************************/
1321tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid) {
1322 NFC_HDR* p_cmd;
1323 uint8_t* p;
1324
1325 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1326
1327 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1328
1329 if (!p_cmd) {
1330 DLOG_IF(INFO, nfc_debug_enabled) << __func__ << "Cannot allocate buffer";
1331 return NFC_STATUS_NO_BUFFERS;
1332 }
1333
1334 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1335 p_cmd->len = 11;
1336 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1337
1338 /* Flags */
1339 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1340 RW_I93_FLAG_DATA_RATE));
1341
1342 /* Command Code */
1343 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_SYS_INFO);
1344
1345 /* Parameters request field */
1346 UINT8_TO_STREAM(p,
1347 (I93_INFO_FLAG_MOI | I93_INFO_FLAG_DSFID | I93_INFO_FLAG_AFI |
1348 I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_IC_REF));
1349
1350 /* Parameters */
1351 if (p_uid) {
1352 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1353 } else {
1354 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1355 }
1356
1357 if (rw_i93_send_to_lower(p_cmd)) {
1358 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_SYS_INFO;
1359 return NFC_STATUS_OK;
1360 } else {
1361 return NFC_STATUS_FAILED;
1362 }
1363}
1364
1365/*******************************************************************************
1366**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001367** Function rw_i93_send_cmd_get_sys_info
1368**
1369** Description Send Get System Information Request to VICC
1370**
1371** Returns tNFC_STATUS
1372**
1373*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001374tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1375 NFC_HDR* p_cmd;
1376 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001377
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001378 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001379
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001380 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001381
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001382 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001383 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001384 return NFC_STATUS_NO_BUFFERS;
1385 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001386
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001387 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1388 p_cmd->len = 10;
1389 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001390
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001391 /* Flags */
1392 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1393 RW_I93_FLAG_DATA_RATE | extra_flags));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001394
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001395 /* Command Code */
1396 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001397
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001398 /* Parameters */
1399 if (p_uid) {
1400 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1401 } else {
1402 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1403 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001404
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001405 if (rw_i93_send_to_lower(p_cmd)) {
1406 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1407 return NFC_STATUS_OK;
1408 } else {
1409 return NFC_STATUS_FAILED;
1410 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001411}
1412
1413/*******************************************************************************
1414**
1415** Function rw_i93_send_cmd_get_multi_block_sec
1416**
1417** Description Send Get Multiple Block Security Status Request to VICC
1418**
1419** Returns tNFC_STATUS
1420**
1421*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001422tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1423 uint16_t number_blocks) {
1424 NFC_HDR* p_cmd;
1425 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001426
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001427 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001428
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001429 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001430
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001431 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001432 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001433 return NFC_STATUS_NO_BUFFERS;
1434 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001435
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001436 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1437 p_cmd->len = 12;
1438 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001439
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001440 /* Flags */
1441 flags =
1442 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -05001443
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001444 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1445 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -05001446
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001447 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001448
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001449 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001450 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1451 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_MULTI_BLK_SEC);
1452 } else {
1453 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1454 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001455
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001456 /* Parameters */
1457 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001458
Raphael Collado867d5c32017-03-27 12:49:40 +02001459 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1460 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001461 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1462 UINT16_TO_STREAM(
1463 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1464 p_cmd->len += 2;
1465 } else {
1466 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1467 UINT8_TO_STREAM(
1468 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1469 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001470
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001471 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001472 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1473 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_MULTI_BLK_SEC;
1474 else
1475 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001476 return NFC_STATUS_OK;
1477 } else {
1478 return NFC_STATUS_FAILED;
1479 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001480}
1481
1482/*******************************************************************************
1483**
1484** Function rw_i93_get_next_blocks
1485**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001486** Description Read as many blocks as possible (up to
1487** RW_I93_READ_MULTI_BLOCK_SIZE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001488**
1489** Returns tNFC_STATUS
1490**
1491*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001492tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1493 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1494 uint16_t first_block;
1495 uint16_t num_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001496
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001497 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001498
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001499 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001500
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001501 /* more blocks, more efficent but more error rate */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001502
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001503 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1504 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001505
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001506 if (num_block + first_block > p_i93->num_block)
1507 num_block = p_i93->num_block - first_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001508
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001509 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
1510 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1511 ** - The max number of blocks is 32 and they are all located in the
1512 ** same sector.
1513 ** - The sector is 32 blocks of 4 bytes.
1514 */
1515 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1516 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1517 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1518 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
1519 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1520 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1521 num_block = I93_STM_MAX_BLOCKS_PER_READ;
Evan Chu85b7e842013-01-18 11:02:50 -05001522
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001523 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1524 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1525 num_block = I93_STM_BLOCKS_PER_SECTOR -
1526 (first_block % I93_STM_BLOCKS_PER_SECTOR);
Evan Chu85b7e842013-01-18 11:02:50 -05001527 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001528 }
1529 }
Evan Chu85b7e842013-01-18 11:02:50 -05001530
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001531 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1532 } else {
1533 return rw_i93_send_cmd_read_single_block(first_block, false);
1534 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001535}
1536
1537/*******************************************************************************
1538**
Evan Chu85b7e842013-01-18 11:02:50 -05001539** Function rw_i93_get_next_block_sec
1540**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001541** Description Get as many security of blocks as possible from
1542** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
Evan Chu85b7e842013-01-18 11:02:50 -05001543**
1544** Returns tNFC_STATUS
1545**
1546*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001547tNFC_STATUS rw_i93_get_next_block_sec(void) {
1548 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1549 uint16_t num_blocks;
Evan Chu85b7e842013-01-18 11:02:50 -05001550
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001551 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001552
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001553 if (p_i93->num_block <= p_i93->rw_offset) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001554 LOG(ERROR) << StringPrintf(
1555 "rw_offset(0x%x) must be less than num_block(0x%x)", p_i93->rw_offset,
1556 p_i93->num_block);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001557 return NFC_STATUS_FAILED;
1558 }
Evan Chu85b7e842013-01-18 11:02:50 -05001559
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001560 num_blocks = p_i93->num_block - p_i93->rw_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001561
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001562 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1563 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
Evan Chu85b7e842013-01-18 11:02:50 -05001564
Raphael Collado867d5c32017-03-27 12:49:40 +02001565 DLOG_IF(INFO, nfc_debug_enabled)
1566 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001567 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
Evan Chu85b7e842013-01-18 11:02:50 -05001568}
1569
1570/*******************************************************************************
1571**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001572** Function rw_i93_sm_detect_ndef
1573**
1574** Description Process NDEF detection procedure
1575**
1576** 1. Get UID if not having yet
1577** 2. Get System Info if not having yet
1578** 3. Read first block for CC
1579** 4. Search NDEF Type and length
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001580** 5. Get block status to get max NDEF size and read-only
1581** status
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001582**
1583** Returns void
1584**
1585*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001586void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001587 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001588 uint8_t flags, u8 = 0, cc[4];
1589 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1590 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1591 tRW_DATA rw_data;
1592 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001593
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001594 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1595 "sub_state:%s (0x%x)",
1596 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 -08001597
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001598 STREAM_TO_UINT8(flags, p);
1599 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001601 if (flags & I93_FLAG_ERROR_DETECTED) {
1602 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1603 /* getting system info with protocol extension flag */
1604 /* This STM tag supports more than 2040 bytes */
1605 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1606 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001607 DLOG_IF(INFO, nfc_debug_enabled)
1608 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001609 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001610 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001611 return;
1612 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001614 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001615 case RW_I93_SUBSTATE_WAIT_UID:
1616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001617 STREAM_TO_UINT8(u8, p); /* DSFID */
1618 p_uid = p_i93->uid;
1619 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001621 if (u8 != I93_DFS_UNSUPPORTED) {
1622 /* if Data Storage Format is unknown */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001623 DLOG_IF(INFO, nfc_debug_enabled)
1624 << StringPrintf("Got unknown DSFID (0x%02x)", u8);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001625 rw_i93_handle_error(NFC_STATUS_FAILED);
1626 } else {
1627 /* get system information to get memory size */
1628 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
1629 NFC_STATUS_OK) {
1630 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1631 } else {
1632 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001633 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001634 }
1635 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001636
1637 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1638
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001639 p_i93->block_size = 0;
1640 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001641
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001642 if (!rw_i93_process_sys_info(p)) {
1643 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001644 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001645 }
1646
1647 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001648 DLOG_IF(INFO, nfc_debug_enabled)
1649 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001650 rw_i93_handle_error(status);
1651 } else {
1652 /* read CC in the first block */
1653 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1654 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1655 } else {
1656 rw_i93_handle_error(NFC_STATUS_FAILED);
1657 }
1658 }
1659 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001660
1661 case RW_I93_SUBSTATE_WAIT_CC:
1662
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001663 /* assume block size is more than 4 */
1664 STREAM_TO_ARRAY(cc, p, 4);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001665
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001666 status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001667
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001668 /*
1669 ** Capability Container (CC)
1670 **
1671 ** CC[0] : magic number (0xE1)
1672 ** CC[1] : Bit 7-6:Major version number
1673 ** : Bit 5-4:Minor version number
1674 ** : Bit 3-2:Read access condition (00b: read access granted
1675 ** without any security)
1676 ** : Bit 1-0:Write access condition (00b: write access granted
1677 ** without any security)
1678 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
1679 ** 0xFF if more than 2040bytes]
1680 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1681 ** : Bit 1:Inventory page read is supported [NXP]
1682 ** : Bit 2:More than 2040 bytes are supported [STM]
1683 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001684
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001685 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1686 "cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
1687 DLOG_IF(INFO, nfc_debug_enabled)
1688 << StringPrintf("Total blocks:0x%04X, Block size:0x%02X",
1689 p_i93->num_block, p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001690
Raphael Collado867d5c32017-03-27 12:49:40 +02001691 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1692 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001693 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1694 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1695 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1696 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1697 /* read-only or password required to write */
1698 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1699 }
1700 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
1701 /* tag supports read multi blocks command */
1702 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1703 }
Raphael Collado867d5c32017-03-27 12:49:40 +02001704 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1705 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1706 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001707 status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001708 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001709 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001710
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001711 if (status == NFC_STATUS_OK) {
1712 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1713 */
1714 if (cc[2] != 0)
1715 p_i93->rw_offset = 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001716 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001717 p_i93->rw_offset = 8;
1718
1719 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1720 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1721 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1722 } else {
1723 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001724 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001725 } else {
1726 rw_i93_handle_error(NFC_STATUS_FAILED);
1727 }
1728 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001729
1730 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1731
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001732 /* search TLV within read blocks */
1733 for (xx = 0; xx < length; xx++) {
1734 /* if looking for type */
1735 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1736 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1737 continue;
1738 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1739 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1740 /* store found type and get length field */
1741 p_i93->tlv_type = *(p + xx);
1742 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001743
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001744 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1745 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1746 /* no NDEF TLV found */
1747 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1748 break;
1749 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001750 DLOG_IF(INFO, nfc_debug_enabled)
1751 << StringPrintf("Invalid type: 0x%02x", *(p + xx));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001752 rw_i93_handle_error(NFC_STATUS_FAILED);
1753 return;
1754 }
1755 } else if (p_i93->tlv_detect_state ==
1756 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
1757 /* if 3 bytes length field */
1758 if (*(p + xx) == 0xFF) {
1759 /* need 2 more bytes for length field */
1760 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1761 } else {
1762 p_i93->tlv_length = *(p + xx);
1763 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1764
1765 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1766 p_i93->ndef_tlv_last_offset =
1767 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1768 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001769 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001770 }
1771 } else if (p_i93->tlv_detect_state ==
1772 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
1773 /* the second byte of 3 bytes length field */
1774 p_i93->tlv_length = *(p + xx);
1775 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1776 } else if (p_i93->tlv_detect_state ==
1777 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
1778 /* the last byte of 3 bytes length field */
1779 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
1780 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001782 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1783 p_i93->ndef_tlv_last_offset =
1784 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1785 break;
1786 }
1787 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
1788 /* this is other than NDEF TLV */
1789 if (p_i93->tlv_length <= length - xx) {
1790 /* skip value field */
1791 xx += (uint8_t)p_i93->tlv_length;
1792 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1793 } else {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001794 /* read more data */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001795 p_i93->tlv_length -= (length - xx);
1796 break;
1797 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001798 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001799 }
1800
1801 /* found NDEF TLV and read length field */
1802 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
1803 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
1804 p_i93->ndef_length = p_i93->tlv_length;
1805
1806 /* get lock status to see if read-only */
1807 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1808 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1809 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1810 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1811 /* these doesn't support GetMultiBlockSecurityStatus */
1812
1813 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
1814 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
1815
1816 /* read block to get lock status */
1817 rw_i93_send_cmd_read_single_block(first_block, true);
1818 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1819 } else {
1820 /* block offset for read-only check */
1821 p_i93->rw_offset = 0;
1822
1823 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
1824 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1825 } else {
1826 rw_i93_handle_error(NFC_STATUS_FAILED);
1827 }
1828 }
1829 } else {
1830 /* read more data */
1831 p_i93->rw_offset += length;
1832
1833 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
1834 rw_i93_handle_error(NFC_STATUS_FAILED);
1835 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1836 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1837 } else {
1838 rw_i93_handle_error(NFC_STATUS_FAILED);
1839 }
1840 }
1841 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001842
1843 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1844
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001845 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1846 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1847 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1848 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1849 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001850
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001851 block = (p_i93->rw_offset / p_i93->block_size);
1852 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001853
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001854 if ((*p) & I93_BLOCK_LOCKED) {
1855 if (block <= last_block) {
1856 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1857 }
1858 } else {
1859 /* if we need to check more user blocks */
1860 if (block + 1 < p_i93->num_block) {
1861 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001862
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001863 /* read block to get lock status */
1864 rw_i93_send_cmd_read_single_block(
1865 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
1866 break;
1867 }
Evan Chu85b7e842013-01-18 11:02:50 -05001868 }
1869
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001870 p_i93->max_ndef_length =
1871 p_i93->ndef_length
1872 /* add available bytes including the last block of NDEF TLV */
1873 + (p_i93->block_size * (block - last_block) + 1) -
1874 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1875 } else {
1876 if (p_i93->rw_offset == 0) {
1877 p_i93->max_ndef_length =
1878 p_i93->ndef_length
1879 /* add available bytes in the last block of NDEF TLV */
1880 + p_i93->block_size -
1881 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1882
1883 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1884 } else {
1885 first_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001886 }
1887
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001888 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1889 num_blocks = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001890
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001891 for (block = first_block; block < num_blocks; block++) {
1892 /* if any block of NDEF TLV is locked */
1893 if ((block + p_i93->rw_offset) <= last_block) {
1894 if (*(p + block) & I93_BLOCK_LOCKED) {
1895 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1896 break;
1897 }
1898 } else {
1899 if (*(p + block) & I93_BLOCK_LOCKED) {
1900 /* no more consecutive unlocked block */
1901 break;
1902 } else {
1903 /* add block size if not locked */
1904 p_i93->max_ndef_length += p_i93->block_size;
1905 }
1906 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001907 }
1908
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001909 /* update next security of block to check */
1910 p_i93->rw_offset += num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001911
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001912 /* if need to check more */
1913 if (p_i93->num_block > p_i93->rw_offset) {
1914 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
1915 rw_i93_handle_error(NFC_STATUS_FAILED);
1916 }
1917 break;
1918 }
1919 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001920
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001921 /* check if need to adjust max NDEF length */
1922 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
1923 /* 3 bytes length field must be used */
1924 p_i93->max_ndef_length -= 2;
1925 }
1926
1927 rw_data.ndef.status = NFC_STATUS_OK;
Love Khanna57a3dfa2017-03-28 20:03:38 +05301928 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001929 rw_data.ndef.flags = 0;
1930 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
1931 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
1932 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
1933 rw_data.ndef.cur_size = p_i93->ndef_length;
1934
1935 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
1936 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1937 rw_data.ndef.max_size = p_i93->ndef_length;
1938 } else {
1939 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
1940 rw_data.ndef.max_size = p_i93->max_ndef_length;
1941 }
1942
1943 p_i93->state = RW_I93_STATE_IDLE;
1944 p_i93->sent_cmd = 0;
1945
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001946 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1947 "NDEF cur_size(%d),max_size (%d), flags (0x%x)",
1948 rw_data.ndef.cur_size, rw_data.ndef.max_size, rw_data.ndef.flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001949
1950 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
1951 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001952
1953 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001954 break;
1955 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001956}
1957
1958/*******************************************************************************
1959**
1960** Function rw_i93_sm_read_ndef
1961**
1962** Description Process NDEF read procedure
1963**
1964** Returns void
1965**
1966*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001967void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
1968 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
1969 uint8_t flags;
1970 uint16_t offset, length = p_resp->len;
1971 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1972 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001973
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001974 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001975
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001976 STREAM_TO_UINT8(flags, p);
1977 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001978
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001979 if (flags & I93_FLAG_ERROR_DETECTED) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001980 DLOG_IF(INFO, nfc_debug_enabled)
1981 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001982 rw_i93_handle_error(NFC_STATUS_FAILED);
1983 return;
1984 }
1985
1986 /* if this is the first block */
1987 if (p_i93->rw_length == 0) {
1988 /* get start of NDEF in the first block */
1989 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
1990
1991 if (p_i93->ndef_length < 0xFF) {
1992 offset += 2;
1993 } else {
1994 offset += 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001995 }
1996
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001997 /* adjust offset if read more blocks because the first block doesn't have
1998 * NDEF */
1999 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
2000 } else {
2001 offset = 0;
2002 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002003
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002004 /* if read enough data to skip type and length field for the beginning */
2005 if (offset < length) {
2006 offset++; /* flags */
2007 p_resp->offset += offset;
2008 p_resp->len -= offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002009
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002010 rw_data.data.status = NFC_STATUS_OK;
2011 rw_data.data.p_data = p_resp;
2012
2013 p_i93->rw_length += p_resp->len;
2014 } else {
2015 /* in case of no Ndef data included */
2016 p_resp->len = 0;
2017 }
2018
2019 /* if read all of NDEF data */
2020 if (p_i93->rw_length >= p_i93->ndef_length) {
2021 /* remove extra btyes in the last block */
2022 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2023
2024 p_i93->state = RW_I93_STATE_IDLE;
2025 p_i93->sent_cmd = 0;
2026
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002027 DLOG_IF(INFO, nfc_debug_enabled)
2028 << StringPrintf("NDEF read complete read (%d)/total (%d)", p_resp->len,
2029 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002030
2031 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2032 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002033 DLOG_IF(INFO, nfc_debug_enabled)
2034 << StringPrintf("NDEF read segment read (%d)/total (%d)", p_resp->len,
2035 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002036
2037 if (p_resp->len > 0) {
2038 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002039 }
2040
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002041 /* this will make read data from next block */
2042 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002043
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002044 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2045 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002046 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002047 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002048}
2049
2050/*******************************************************************************
2051**
2052** Function rw_i93_sm_update_ndef
2053**
2054** Description Process NDEF update procedure
2055**
2056** 1. Set length field to zero
2057** 2. Write NDEF and Terminator TLV
2058** 3. Set length field to NDEF length
2059**
2060** Returns void
2061**
2062*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002063void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
2064 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2065 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2066 uint16_t length = p_resp->len, block_number;
2067 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2068 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002069
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002070 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2071 "sub_state:%s (0x%x)",
2072 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 -08002073
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002074 STREAM_TO_UINT8(flags, p);
2075 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002076
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002077 if (flags & I93_FLAG_ERROR_DETECTED) {
2078 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2079 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2080 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2081 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2082 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2083 /* ignore error */
2084 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002085 DLOG_IF(INFO, nfc_debug_enabled)
2086 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002087 rw_i93_handle_error(NFC_STATUS_FAILED);
2088 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002089 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002090 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002091
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002092 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002093 case RW_I93_SUBSTATE_RESET_LEN:
2094
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002095 /* get offset of length field */
2096 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002097
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002098 /* set length to zero */
2099 *(p + length_offset) = 0x00;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002100
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002101 if (p_i93->ndef_length > 0) {
2102 /* if 3 bytes length field is needed */
2103 if (p_i93->ndef_length >= 0xFF) {
2104 xx = length_offset + 3;
2105 } else {
2106 xx = length_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002107 }
2108
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002109 /* write the first part of NDEF in the same block */
2110 for (; xx < p_i93->block_size; xx++) {
2111 if (p_i93->rw_length < p_i93->ndef_length) {
2112 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2113 } else {
2114 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2115 }
2116 }
2117 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002118
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002119 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2120
2121 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2122 NFC_STATUS_OK) {
2123 /* update next writing offset */
2124 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2125 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2126 } else {
2127 rw_i93_handle_error(NFC_STATUS_FAILED);
2128 }
2129 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002130
2131 case RW_I93_SUBSTATE_WRITE_NDEF:
2132
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002133 /* if it's not the end of tag memory */
2134 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
2135 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002136
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002137 /* if we have more data to write */
2138 if (p_i93->rw_length < p_i93->ndef_length) {
2139 p = p_i93->p_update_data + p_i93->rw_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002140
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002141 p_i93->rw_offset += p_i93->block_size;
2142 p_i93->rw_length += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002143
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002144 /* if this is the last block of NDEF TLV */
2145 if (p_i93->rw_length > p_i93->ndef_length) {
2146 /* length of NDEF TLV in the block */
2147 xx = (uint8_t)(p_i93->block_size -
2148 (p_i93->rw_length - p_i93->ndef_length));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002149
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002150 /* set NULL TLV in the unused part of block */
2151 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2152 memcpy(buff, p, xx);
2153 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002154
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002155 /* if it's the end of tag memory */
2156 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2157 (xx < p_i93->block_size)) {
2158 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002159 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002160
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002161 p_i93->ndef_tlv_last_offset =
2162 p_i93->rw_offset - p_i93->block_size + xx - 1;
2163 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002164
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002165 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2166 NFC_STATUS_OK) {
2167 rw_i93_handle_error(NFC_STATUS_FAILED);
2168 }
2169 } else {
2170 /* if this is the very next block of NDEF TLV */
2171 if (block_number ==
2172 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2173 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002174
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002175 /* write Terminator TLV and NULL TLV */
2176 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2177 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2178 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002179
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002180 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2181 NFC_STATUS_OK) {
2182 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002183 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002184 } else {
2185 /* finished writing NDEF and Terminator TLV */
2186 /* read length field to update length */
2187 block_number =
2188 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2189
2190 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2191 NFC_STATUS_OK) {
2192 /* set offset to length field */
2193 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2194
2195 /* get size of length field */
2196 if (p_i93->ndef_length >= 0xFF) {
2197 p_i93->rw_length = 3;
2198 } else if (p_i93->ndef_length > 0) {
2199 p_i93->rw_length = 1;
2200 } else {
2201 p_i93->rw_length = 0;
2202 }
2203
2204 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2205 } else {
2206 rw_i93_handle_error(NFC_STATUS_FAILED);
2207 }
2208 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002209 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002210 } else {
2211 /* if we have no more data to write */
2212 if (p_i93->rw_length >= p_i93->ndef_length) {
2213 /* finished writing NDEF and Terminator TLV */
2214 /* read length field to update length */
2215 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002216
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002217 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2218 NFC_STATUS_OK) {
2219 /* set offset to length field */
2220 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002221
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002222 /* get size of length field */
2223 if (p_i93->ndef_length >= 0xFF) {
2224 p_i93->rw_length = 3;
2225 } else if (p_i93->ndef_length > 0) {
2226 p_i93->rw_length = 1;
2227 } else {
2228 p_i93->rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002229 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002230
2231 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2232 break;
2233 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002234 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002235 rw_i93_handle_error(NFC_STATUS_FAILED);
2236 }
2237 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002238
2239 case RW_I93_SUBSTATE_UPDATE_LEN:
2240
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002241 /* if we have more length field to write */
2242 if (p_i93->rw_length > 0) {
2243 /* if we got ack for writing, read next block to update rest of length
2244 * field */
2245 if (length == 0) {
2246 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002247
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002248 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2249 NFC_STATUS_OK) {
2250 rw_i93_handle_error(NFC_STATUS_FAILED);
2251 }
2252 } else {
2253 length_offset = p_i93->rw_offset % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002254
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002255 /* update length field within the read block */
2256 for (xx = length_offset; xx < p_i93->block_size; xx++) {
2257 if (p_i93->rw_length == 3)
2258 *(p + xx) = 0xFF;
2259 else if (p_i93->rw_length == 2)
2260 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2261 else if (p_i93->rw_length == 1)
2262 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002263
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002264 p_i93->rw_length--;
2265 if (p_i93->rw_length == 0) break;
2266 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002267
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002268 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002269
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002270 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2271 NFC_STATUS_OK) {
2272 /* set offset to the beginning of next block */
2273 p_i93->rw_offset +=
2274 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2275 } else {
2276 rw_i93_handle_error(NFC_STATUS_FAILED);
2277 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002278 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002279 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002280 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2281 "NDEF update complete, %d bytes, (%d-%d)", p_i93->ndef_length,
2282 p_i93->ndef_tlv_start_offset, p_i93->ndef_tlv_last_offset);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002283
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002284 p_i93->state = RW_I93_STATE_IDLE;
2285 p_i93->sent_cmd = 0;
2286 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002287
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002288 rw_data.status = NFC_STATUS_OK;
2289 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2290 }
2291 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002292
2293 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002294 break;
2295 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002296}
2297
2298/*******************************************************************************
2299**
2300** Function rw_i93_sm_format
2301**
2302** Description Process format procedure
2303**
2304** 1. Get UID
2305** 2. Get sys info for memory size (reset AFI/DSFID)
2306** 3. Get block status to get read-only status
2307** 4. Write CC and empty NDEF
2308**
2309** Returns void
2310**
2311*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002312void rw_i93_sm_format(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002313 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002314 uint8_t flags;
2315 uint16_t length = p_resp->len, xx, block_number;
2316 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2317 tRW_DATA rw_data;
2318 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002319
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002320 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2321 "sub_state:%s (0x%x)",
2322 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 -08002323
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002324 STREAM_TO_UINT8(flags, p);
2325 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002326
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002327 if (flags & I93_FLAG_ERROR_DETECTED) {
2328 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2329 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2330 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2331 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2332 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2333 /* ignore error */
2334 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2335 /* getting system info with protocol extension flag */
2336 /* This STM tag supports more than 2040 bytes */
2337 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2338 return;
2339 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002340 DLOG_IF(INFO, nfc_debug_enabled)
2341 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002342 rw_i93_handle_error(NFC_STATUS_FAILED);
2343 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002344 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002345 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002346
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002347 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002348 case RW_I93_SUBSTATE_WAIT_UID:
2349
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002350 p++; /* skip DSFID */
2351 p_uid = p_i93->uid;
2352 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002353
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002354 /* get system information to get memory size */
2355 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
2356 NFC_STATUS_OK) {
2357 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2358 } else {
2359 rw_i93_handle_error(NFC_STATUS_FAILED);
2360 }
2361 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002362
2363 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2364
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002365 p_i93->block_size = 0;
2366 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002367
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002368 if (!rw_i93_process_sys_info(p)) {
2369 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002370 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002371 }
2372
2373 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2374 /* DSFID, if any DSFID then reset */
2375 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2376 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2377 }
2378 }
2379 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2380 /* AFI, reset to 0 */
2381 if (p_i93->afi != 0x00) {
2382 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2383 }
2384 }
2385
2386 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002387 DLOG_IF(INFO, nfc_debug_enabled)
2388 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002389 rw_i93_handle_error(status);
2390 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2391 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2392 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2393 } else {
2394 rw_i93_handle_error(NFC_STATUS_FAILED);
2395 }
2396 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2397 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2398 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2399 } else {
2400 rw_i93_handle_error(NFC_STATUS_FAILED);
2401 }
2402 } else {
2403 /* get lock status to see if read-only */
2404 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2405 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2406 /* these doesn't support GetMultiBlockSecurityStatus */
2407
2408 rw_cb.tcb.i93.rw_offset = 0;
2409
2410 /* read blocks with option flag to get block security status */
2411 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2412 NFC_STATUS_OK) {
2413 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2414 } else {
2415 rw_i93_handle_error(NFC_STATUS_FAILED);
2416 }
2417 } else {
2418 /* block offset for read-only check */
2419 p_i93->rw_offset = 0;
2420
2421 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2422 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2423 } else {
2424 rw_i93_handle_error(NFC_STATUS_FAILED);
2425 }
2426 }
2427 }
2428
2429 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002430
2431 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2432
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002433 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2434 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2435 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2436 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2437 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002438
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002439 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2440 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2441 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2442 } else {
2443 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002444 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002445 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2446 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2447 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2448 } else {
2449 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002450 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002451 } else {
2452 /* get lock status to see if read-only */
2453 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2454 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2455 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002456
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002457 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002458
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002459 /* read blocks with option flag to get block security status */
2460 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2461 NFC_STATUS_OK) {
2462 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2463 } else {
2464 rw_i93_handle_error(NFC_STATUS_FAILED);
2465 }
2466 } else {
2467 /* block offset for read-only check */
2468 p_i93->rw_offset = 0;
Evan Chu85b7e842013-01-18 11:02:50 -05002469
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002470 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2471 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2472 } else {
2473 rw_i93_handle_error(NFC_STATUS_FAILED);
2474 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002475 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002476 }
2477 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002478
2479 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2480
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002481 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2482 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2483 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2484 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2485 if ((*p) & I93_BLOCK_LOCKED) {
2486 rw_i93_handle_error(NFC_STATUS_FAILED);
2487 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002488 }
2489
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002490 /* if we checked all of user blocks */
2491 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2492 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2493 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2494 /* read the block which has AFI */
2495 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2496 rw_i93_send_cmd_read_single_block(
2497 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002498 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002499 }
2500 } else if (p_i93->rw_offset ==
2501 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2502 /* no block is locked */
2503 } else {
2504 p_i93->rw_offset += p_i93->block_size;
2505 rw_i93_send_cmd_read_single_block(
2506 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2507 break;
2508 }
2509 } else {
2510 /* if any block is locked, we cannot format it */
2511 for (xx = 0; xx < length; xx++) {
2512 if (*(p + xx) & I93_BLOCK_LOCKED) {
2513 rw_i93_handle_error(NFC_STATUS_FAILED);
2514 break;
2515 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002516 }
2517
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002518 /* update block offset for read-only check */
2519 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002520
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002521 /* if need to get more lock status of blocks */
2522 if (p_i93->num_block > p_i93->rw_offset) {
2523 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2524 rw_i93_handle_error(NFC_STATUS_FAILED);
2525 }
2526 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002527 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002528 }
Evan Chu85b7e842013-01-18 11:02:50 -05002529
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002530 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2531 p_i93->p_update_data = (uint8_t*)GKI_getbuf(RW_I93_FORMAT_DATA_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002532
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002533 if (!p_i93->p_update_data) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002534 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002535 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002536 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002537 }
2538
2539 p = p_i93->p_update_data;
2540
2541 /* Capability Container */
Raphael Collado867d5c32017-03-27 12:49:40 +02002542 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002543 *(p++) = 0x40; /* version 1.0, read/write */
2544
2545 /* if memory size is less than 2048 bytes */
2546 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2547 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2548 8); /* memory size */
2549 else
2550 *(p++) = 0xFF;
2551
2552 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2553 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2554 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2555 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2556 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2557 else
2558 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2559 supported */
2560 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2561 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2562 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2563 supported */
2564 } else if ((p_i93->product_version ==
2565 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2566 (p_i93->product_version ==
2567 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2568 *(p++) = 0;
2569 } else {
2570 /* STM except LRIS2K, Broadcom supports read multi block command */
2571
2572 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2573 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2574 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2575 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2576 *(p++) = 0x00;
2577 else
2578 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2579 }
2580
2581 /* zero length NDEF and Terminator TLV */
2582 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2583 *(p++) = 0x00;
2584 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2585 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2586
2587 /* start from block 0 */
2588 p_i93->rw_offset = 0;
2589
2590 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2591 NFC_STATUS_OK) {
2592 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2593 p_i93->rw_offset += p_i93->block_size;
2594 } else {
2595 rw_i93_handle_error(NFC_STATUS_FAILED);
2596 }
2597 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002598
2599 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002601 /* if we have more data to write */
2602 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2603 block_number = (p_i93->rw_offset / p_i93->block_size);
2604 p = p_i93->p_update_data + p_i93->rw_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002605
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002606 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2607 NFC_STATUS_OK) {
2608 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2609 p_i93->rw_offset += p_i93->block_size;
2610 } else {
2611 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002612 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002613 } else {
2614 GKI_freebuf(p_i93->p_update_data);
2615 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002617 p_i93->state = RW_I93_STATE_IDLE;
2618 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002619
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002620 rw_data.status = NFC_STATUS_OK;
2621 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2622 }
2623 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002624
2625 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002626 break;
2627 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002628}
2629
2630/*******************************************************************************
2631**
2632** Function rw_i93_sm_set_read_only
2633**
2634** Description Process read-only procedure
2635**
2636** 1. Update CC as read-only
2637** 2. Lock all block of NDEF TLV
2638** 3. Lock block of CC
2639**
2640** Returns void
2641**
2642*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002643void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2644 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2645 uint8_t flags, block_number;
2646 uint16_t length = p_resp->len;
2647 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2648 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002649
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002650 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2651 "sub_state:%s (0x%x)",
2652 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 -08002653
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002654 STREAM_TO_UINT8(flags, p);
2655 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002656
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002657 if (flags & I93_FLAG_ERROR_DETECTED) {
2658 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2659 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2660 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2661 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2662 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2663 /* ignore error */
2664 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002665 DLOG_IF(INFO, nfc_debug_enabled)
2666 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002667 rw_i93_handle_error(NFC_STATUS_FAILED);
2668 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002669 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002670 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002672 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002673 case RW_I93_SUBSTATE_WAIT_CC:
2674
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002675 /* mark CC as read-only */
2676 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002678 if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
2679 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2680 } else {
2681 rw_i93_handle_error(NFC_STATUS_FAILED);
2682 }
2683 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002684
2685 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002687 /* successfully write CC then lock all blocks of NDEF TLV */
2688 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2689 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002690
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002691 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2692 p_i93->rw_offset += p_i93->block_size;
2693 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2694 } else {
2695 rw_i93_handle_error(NFC_STATUS_FAILED);
2696 }
2697 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002698
2699 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2700
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002701 /* if we need to lock more blocks */
2702 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
2703 /* get the next block of NDEF TLV */
2704 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002705
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002706 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2707 p_i93->rw_offset += p_i93->block_size;
2708 } else {
2709 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002710 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002711 }
2712 /* if the first block of NDEF TLV is different from block of CC */
2713 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
2714 /* lock block of CC */
2715 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
2716 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2717 } else {
2718 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002719 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002720 } else {
2721 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2722 p_i93->state = RW_I93_STATE_IDLE;
2723 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002724
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002725 rw_data.status = NFC_STATUS_OK;
2726 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2727 }
2728 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002729
2730 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2731
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002732 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2733 p_i93->state = RW_I93_STATE_IDLE;
2734 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002735
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002736 rw_data.status = NFC_STATUS_OK;
2737 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2738 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002739
2740 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002741 break;
2742 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002743}
2744
2745/*******************************************************************************
2746**
2747** Function rw_i93_handle_error
2748**
2749** Description notify error to application and clean up
2750**
2751** Returns none
2752**
2753*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002754void rw_i93_handle_error(tNFC_STATUS status) {
2755 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2756 tRW_DATA rw_data;
2757 tRW_EVENT event;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002758
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002759 DLOG_IF(INFO, nfc_debug_enabled)
2760 << StringPrintf("status:0x%02X, state:0x%X", status, p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002761
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002762 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002763
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002764 if (rw_cb.p_cback) {
2765 rw_data.status = status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002766
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002767 switch (p_i93->state) {
2768 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2769 event = RW_I93_INTF_ERROR_EVT;
2770 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002771
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002772 case RW_I93_STATE_BUSY:
2773 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
2774 /* There is no response to Stay Quiet command */
2775 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2776 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2777 rw_data.i93_cmd_cmpl.error_code = 0;
2778 event = RW_I93_CMD_CMPL_EVT;
2779 } else {
2780 event = RW_I93_INTF_ERROR_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002781 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002782 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002783
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002784 case RW_I93_STATE_DETECT_NDEF:
Love Khanna57a3dfa2017-03-28 20:03:38 +05302785 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002786 rw_data.ndef.cur_size = 0;
2787 rw_data.ndef.max_size = 0;
2788 rw_data.ndef.flags = 0;
2789 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2790 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2791 event = RW_I93_NDEF_DETECT_EVT;
2792 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002793
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002794 case RW_I93_STATE_READ_NDEF:
2795 event = RW_I93_NDEF_READ_FAIL_EVT;
2796 break;
2797
2798 case RW_I93_STATE_UPDATE_NDEF:
2799 p_i93->p_update_data = NULL;
2800 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2801 break;
2802
2803 case RW_I93_STATE_FORMAT:
2804 if (p_i93->p_update_data) {
2805 GKI_freebuf(p_i93->p_update_data);
2806 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002807 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002808 event = RW_I93_FORMAT_CPLT_EVT;
2809 break;
2810
2811 case RW_I93_STATE_SET_READ_ONLY:
2812 event = RW_I93_SET_TAG_RO_EVT;
2813 break;
2814
2815 case RW_I93_STATE_PRESENCE_CHECK:
2816 event = RW_I93_PRESENCE_CHECK_EVT;
2817 break;
2818
2819 default:
2820 event = RW_I93_MAX_EVT;
2821 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002822 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002823
2824 p_i93->state = RW_I93_STATE_IDLE;
2825 p_i93->sent_cmd = 0;
2826
2827 if (event != RW_I93_MAX_EVT) {
2828 (*(rw_cb.p_cback))(event, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002829 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002830 } else {
2831 p_i93->state = RW_I93_STATE_IDLE;
2832 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002833}
2834
2835/*******************************************************************************
2836**
2837** Function rw_i93_process_timeout
2838**
2839** Description process timeout event
2840**
2841** Returns none
2842**
2843*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002844void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2845 NFC_HDR* p_buf;
Evan Chu85b7e842013-01-18 11:02:50 -05002846
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002847 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002848
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002849 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
2850 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
2851 (rw_cb.tcb.i93.p_retry_cmd) &&
2852 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
2853 rw_cb.tcb.i93.retry_count++;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002854 LOG(ERROR) << StringPrintf("retry_count = %d", rw_cb.tcb.i93.retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05002855
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002856 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2857 rw_cb.tcb.i93.p_retry_cmd = NULL;
Evan Chu7c69b272013-05-14 12:48:36 -04002858
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002859 if (rw_i93_send_to_lower(p_buf)) {
2860 return;
2861 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002862 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002863
2864 /* all retrial is done or failed to send command to lower layer */
2865 if (rw_cb.tcb.i93.p_retry_cmd) {
2866 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
2867 rw_cb.tcb.i93.p_retry_cmd = NULL;
2868 rw_cb.tcb.i93.retry_count = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002869 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002870 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
2871 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002872 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002873 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002874}
2875
2876/*******************************************************************************
2877**
2878** Function rw_i93_data_cback
2879**
2880** Description This callback function receives the data from NFCC.
2881**
2882** Returns none
2883**
2884*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002885static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
2886 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002887 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2888 NFC_HDR* p_resp;
2889 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002890
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002891 uint8_t begin_state = p_i93->state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002892
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002893 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002894
Love Khanna57a3dfa2017-03-28 20:03:38 +05302895 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
2896 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002897 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002898
Jizhou Liao499be102017-08-11 12:57:12 -07002899 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002900 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
2901 p_i93->retry_count++;
Evan Chu85b7e842013-01-18 11:02:50 -05002902
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002903 LOG(ERROR) << StringPrintf("retry_count = %d", p_i93->retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05002904
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002905 p_resp = p_i93->p_retry_cmd;
2906 p_i93->p_retry_cmd = NULL;
2907 if (rw_i93_send_to_lower(p_resp)) {
2908 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002909 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002910 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002911
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002912 /* all retrial is done or failed to send command to lower layer */
2913 if (p_i93->p_retry_cmd) {
2914 GKI_freebuf(p_i93->p_retry_cmd);
Evan Chu85b7e842013-01-18 11:02:50 -05002915 p_i93->p_retry_cmd = NULL;
2916 p_i93->retry_count = 0;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002917 }
2918
2919 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
2920 } else {
2921 /* free retry buffer */
2922 if (p_i93->p_retry_cmd) {
2923 GKI_freebuf(p_i93->p_retry_cmd);
2924 p_i93->p_retry_cmd = NULL;
2925 p_i93->retry_count = 0;
2926 }
2927 NFC_SetStaticRfCback(NULL);
2928 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
Evan Chu85b7e842013-01-18 11:02:50 -05002929 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002930 return;
2931 }
2932
2933 if (event != NFC_DATA_CEVT) {
2934 return;
2935 }
2936
2937 p_resp = (NFC_HDR*)p_data->data.p_data;
2938
2939 nfc_stop_quick_timer(&p_i93->timer);
2940
2941 /* free retry buffer */
2942 if (p_i93->p_retry_cmd) {
2943 GKI_freebuf(p_i93->p_retry_cmd);
2944 p_i93->p_retry_cmd = NULL;
2945 p_i93->retry_count = 0;
2946 }
Evan Chu85b7e842013-01-18 11:02:50 -05002947
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002948 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2949 "RW I93 state: <%s (%d)>", rw_i93_get_state_name(p_i93->state).c_str(),
2950 p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002952 switch (p_i93->state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002953 case RW_I93_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002954 /* Unexpected Response from VICC, it should be raw frame response */
2955 /* forward to upper layer without parsing */
2956 p_i93->sent_cmd = 0;
2957 if (rw_cb.p_cback) {
2958 rw_data.raw_frame.status = p_data->data.status;
2959 rw_data.raw_frame.p_data = p_resp;
2960 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
2961 p_resp = NULL;
2962 } else {
2963 GKI_freebuf(p_resp);
2964 }
2965 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002966 case RW_I93_STATE_BUSY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002967 p_i93->state = RW_I93_STATE_IDLE;
2968 rw_i93_send_to_upper(p_resp);
2969 GKI_freebuf(p_resp);
2970 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002971
2972 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002973 rw_i93_sm_detect_ndef(p_resp);
2974 GKI_freebuf(p_resp);
2975 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002976
2977 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002978 rw_i93_sm_read_ndef(p_resp);
2979 /* p_resp may send upper lyaer */
2980 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002981
2982 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002983 rw_i93_sm_update_ndef(p_resp);
2984 GKI_freebuf(p_resp);
2985 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002986
2987 case RW_I93_STATE_FORMAT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002988 rw_i93_sm_format(p_resp);
2989 GKI_freebuf(p_resp);
2990 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002991
2992 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002993 rw_i93_sm_set_read_only(p_resp);
2994 GKI_freebuf(p_resp);
2995 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002996
2997 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002998 p_i93->state = RW_I93_STATE_IDLE;
2999 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003000
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003001 /* if any response, send presence check with ok */
3002 rw_data.status = NFC_STATUS_OK;
3003 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3004 GKI_freebuf(p_resp);
3005 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003006
3007 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003008 LOG(ERROR) << StringPrintf("invalid state=%d", p_i93->state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003009 GKI_freebuf(p_resp);
3010 break;
3011 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003012
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003013 if (begin_state != p_i93->state) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003014 DLOG_IF(INFO, nfc_debug_enabled)
3015 << StringPrintf("RW I93 state changed:<%s> -> <%s>",
3016 rw_i93_get_state_name(begin_state).c_str(),
3017 rw_i93_get_state_name(p_i93->state).c_str());
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003018 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003019}
3020
3021/*******************************************************************************
3022**
3023** Function rw_i93_select
3024**
Love Khanna57a3dfa2017-03-28 20:03:38 +05303025** Description Initialise ISO 15693 / T5T RW
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003026**
3027** Returns NFC_STATUS_OK if success
3028**
3029*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003030tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
3031 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3032 uint8_t uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003033
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003034 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003035
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003036 NFC_SetStaticRfCback(rw_i93_data_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003037
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003038 p_i93->state = RW_I93_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003039
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003040 /* convert UID to big endian format - MSB(0xE0) in first byte */
3041 p = uid;
3042 STREAM_TO_ARRAY8(p, p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003043
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003044 rw_i93_get_product_version(uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003045
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003046 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003047}
3048
3049/*******************************************************************************
3050**
3051** Function RW_I93Inventory
3052**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003053** Description This function send Inventory command with/without AFI
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003054** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3055**
3056** RW_I93_RESPONSE_EVT will be returned
3057**
3058** Returns NFC_STATUS_OK if success
3059** NFC_STATUS_NO_BUFFERS if out of buffer
3060** NFC_STATUS_BUSY if busy
3061** NFC_STATUS_FAILED if other error
3062**
3063*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003064tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3065 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003066
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003067 DLOG_IF(INFO, nfc_debug_enabled)
3068 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003069
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003070 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003071 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3072 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003073 return NFC_STATUS_BUSY;
3074 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003075
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003076 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003078 if (status == NFC_STATUS_OK) {
3079 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3080 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003081
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003082 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003083}
3084
3085/*******************************************************************************
3086**
3087** Function RW_I93StayQuiet
3088**
3089** Description This function send Inventory command
3090**
3091** RW_I93_CMD_CMPL_EVT will be returned
3092**
3093** Returns NFC_STATUS_OK if success
3094** NFC_STATUS_NO_BUFFERS if out of buffer
3095** NFC_STATUS_BUSY if busy
3096** NFC_STATUS_FAILED if other error
3097**
3098*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003099tNFC_STATUS RW_I93StayQuiet(void) {
3100 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003101
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003102 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003103
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003104 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003105 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3106 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003107 return NFC_STATUS_BUSY;
3108 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003109
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003110 status = rw_i93_send_cmd_stay_quiet();
3111 if (status == NFC_STATUS_OK) {
3112 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3113 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003114
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003115 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003116}
3117
3118/*******************************************************************************
3119**
3120** Function RW_I93ReadSingleBlock
3121**
3122** Description This function send Read Single Block command
3123**
3124** RW_I93_RESPONSE_EVT will be returned
3125**
3126** Returns NFC_STATUS_OK if success
3127** NFC_STATUS_NO_BUFFERS if out of buffer
3128** NFC_STATUS_BUSY if busy
3129** NFC_STATUS_FAILED if other error
3130**
3131*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003132tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3133 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003134
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003135 DLOG_IF(INFO, nfc_debug_enabled)
3136 << StringPrintf("block_number:0x%02X", block_number);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003137
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003138 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003139 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3140 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003141 return NFC_STATUS_BUSY;
3142 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003143
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003144 status = rw_i93_send_cmd_read_single_block(block_number, false);
3145 if (status == NFC_STATUS_OK) {
3146 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3147 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003149 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003150}
3151
3152/*******************************************************************************
3153**
3154** Function RW_I93WriteSingleBlock
3155**
3156** Description This function send Write Single Block command
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003157** Application must get block size first by calling
3158** RW_I93GetSysInfo().
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003159**
3160** RW_I93_CMD_CMPL_EVT will be returned
3161**
3162** Returns NFC_STATUS_OK if success
3163** NFC_STATUS_NO_BUFFERS if out of buffer
3164** NFC_STATUS_BUSY if busy
3165** NFC_STATUS_FAILED if other error
3166**
3167*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003168tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3169 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003170
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003171 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003172
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003173 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003174 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3175 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003176 return NFC_STATUS_BUSY;
3177 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003179 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003180 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003181 return NFC_STATUS_FAILED;
3182 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003183
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003184 status = rw_i93_send_cmd_write_single_block(block_number, p_data);
3185 if (status == NFC_STATUS_OK) {
3186 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3187 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003189 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003190}
3191
3192/*******************************************************************************
3193**
3194** Function RW_I93LockBlock
3195**
3196** Description This function send Lock Block command
3197**
3198** RW_I93_CMD_CMPL_EVT will be returned
3199**
3200** Returns NFC_STATUS_OK if success
3201** NFC_STATUS_NO_BUFFERS if out of buffer
3202** NFC_STATUS_BUSY if busy
3203** NFC_STATUS_FAILED if other error
3204**
3205*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003206tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3207 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003208
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003209 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003210
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003211 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003212 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3213 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003214 return NFC_STATUS_BUSY;
3215 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003216
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003217 status = rw_i93_send_cmd_lock_block(block_number);
3218 if (status == NFC_STATUS_OK) {
3219 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3220 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003221
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003222 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003223}
3224
3225/*******************************************************************************
3226**
3227** Function RW_I93ReadMultipleBlocks
3228**
3229** Description This function send Read Multiple Blocks command
3230**
3231** RW_I93_RESPONSE_EVT will be returned
3232**
3233** Returns NFC_STATUS_OK if success
3234** NFC_STATUS_NO_BUFFERS if out of buffer
3235** NFC_STATUS_BUSY if busy
3236** NFC_STATUS_FAILED if other error
3237**
3238*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003239tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3240 uint16_t number_blocks) {
3241 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003242
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003243 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003244
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003245 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003246 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3247 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003248 return NFC_STATUS_BUSY;
3249 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003250
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003251 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3252 if (status == NFC_STATUS_OK) {
3253 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3254 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003255
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003256 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003257}
3258
3259/*******************************************************************************
3260**
3261** Function RW_I93WriteMultipleBlocks
3262**
3263** Description This function send Write Multiple Blocks command
3264**
3265** RW_I93_CMD_CMPL_EVT will be returned
3266**
3267** Returns NFC_STATUS_OK if success
3268** NFC_STATUS_NO_BUFFERS if out of buffer
3269** NFC_STATUS_BUSY if busy
3270** NFC_STATUS_FAILED if other error
3271**
3272*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02003273tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003274 uint16_t number_blocks, uint8_t* p_data) {
3275 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003276
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003277 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003278
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003279 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003280 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3281 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003282 return NFC_STATUS_BUSY;
3283 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003284
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003285 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003286 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003287 return NFC_STATUS_FAILED;
3288 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003289
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003290 status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
3291 p_data);
3292 if (status == NFC_STATUS_OK) {
3293 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3294 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003295
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003296 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003297}
3298
3299/*******************************************************************************
3300**
3301** Function RW_I93Select
3302**
3303** Description This function send Select command
3304**
3305** UID[0]: 0xE0, MSB
3306** UID[1]: IC Mfg Code
3307** ...
3308** UID[7]: LSB
3309**
3310** RW_I93_CMD_CMPL_EVT will be returned
3311**
3312** Returns NFC_STATUS_OK if success
3313** NFC_STATUS_NO_BUFFERS if out of buffer
3314** NFC_STATUS_BUSY if busy
3315** NFC_STATUS_FAILED if other error
3316**
3317*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003318tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3319 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003320
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003321 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003322
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003323 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003324 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3325 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003326 return NFC_STATUS_BUSY;
3327 }
3328
3329 if (p_uid) {
3330 status = rw_i93_send_cmd_select(p_uid);
3331 if (status == NFC_STATUS_OK) {
3332 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003333 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003334 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003335 LOG(ERROR) << StringPrintf("UID shall be provided");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003336 status = NFC_STATUS_FAILED;
3337 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003338
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003339 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003340}
3341
3342/*******************************************************************************
3343**
3344** Function RW_I93ResetToReady
3345**
3346** Description This function send Reset To Ready command
3347**
3348** RW_I93_CMD_CMPL_EVT will be returned
3349**
3350** Returns NFC_STATUS_OK if success
3351** NFC_STATUS_NO_BUFFERS if out of buffer
3352** NFC_STATUS_BUSY if busy
3353** NFC_STATUS_FAILED if other error
3354**
3355*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003356tNFC_STATUS RW_I93ResetToReady(void) {
3357 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003358
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003359 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003360
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003361 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003362 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3363 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003364 return NFC_STATUS_BUSY;
3365 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003366
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003367 status = rw_i93_send_cmd_reset_to_ready();
3368 if (status == NFC_STATUS_OK) {
3369 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3370 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003371
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003372 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003373}
3374
3375/*******************************************************************************
3376**
3377** Function RW_I93WriteAFI
3378**
3379** Description This function send Write AFI command
3380**
3381** RW_I93_CMD_CMPL_EVT will be returned
3382**
3383** Returns NFC_STATUS_OK if success
3384** NFC_STATUS_NO_BUFFERS if out of buffer
3385** NFC_STATUS_BUSY if busy
3386** NFC_STATUS_FAILED if other error
3387**
3388*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003389tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3390 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003391
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003392 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003393
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003394 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003395 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3396 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003397 return NFC_STATUS_BUSY;
3398 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003399
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003400 status = rw_i93_send_cmd_write_afi(afi);
3401 if (status == NFC_STATUS_OK) {
3402 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3403 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003404
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003405 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003406}
3407
3408/*******************************************************************************
3409**
3410** Function RW_I93LockAFI
3411**
3412** Description This function send Lock AFI command
3413**
3414** RW_I93_CMD_CMPL_EVT will be returned
3415**
3416** Returns NFC_STATUS_OK if success
3417** NFC_STATUS_NO_BUFFERS if out of buffer
3418** NFC_STATUS_BUSY if busy
3419** NFC_STATUS_FAILED if other error
3420**
3421*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003422tNFC_STATUS RW_I93LockAFI(void) {
3423 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003424
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003425 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003426
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003427 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003428 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3429 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003430 return NFC_STATUS_BUSY;
3431 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003432
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003433 status = rw_i93_send_cmd_lock_afi();
3434 if (status == NFC_STATUS_OK) {
3435 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3436 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003437
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003438 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003439}
3440
3441/*******************************************************************************
3442**
3443** Function RW_I93WriteDSFID
3444**
3445** Description This function send Write DSFID command
3446**
3447** RW_I93_CMD_CMPL_EVT will be returned
3448**
3449** Returns NFC_STATUS_OK if success
3450** NFC_STATUS_NO_BUFFERS if out of buffer
3451** NFC_STATUS_BUSY if busy
3452** NFC_STATUS_FAILED if other error
3453**
3454*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003455tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3456 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003457
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003458 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003459
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003460 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003461 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3462 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003463 return NFC_STATUS_BUSY;
3464 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003465
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003466 status = rw_i93_send_cmd_write_dsfid(dsfid);
3467 if (status == NFC_STATUS_OK) {
3468 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3469 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003470
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003471 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003472}
3473
3474/*******************************************************************************
3475**
3476** Function RW_I93LockDSFID
3477**
3478** Description This function send Lock DSFID command
3479**
3480** RW_I93_CMD_CMPL_EVT will be returned
3481**
3482** Returns NFC_STATUS_OK if success
3483** NFC_STATUS_NO_BUFFERS if out of buffer
3484** NFC_STATUS_BUSY if busy
3485** NFC_STATUS_FAILED if other error
3486**
3487*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003488tNFC_STATUS RW_I93LockDSFID(void) {
3489 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003490
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003491 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003492
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003493 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003494 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3495 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003496 return NFC_STATUS_BUSY;
3497 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003498
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003499 status = rw_i93_send_cmd_lock_dsfid();
3500 if (status == NFC_STATUS_OK) {
3501 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3502 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003503
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003504 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003505}
3506
3507/*******************************************************************************
3508**
3509** Function RW_I93GetSysInfo
3510**
3511** Description This function send Get System Information command
3512**
3513** RW_I93_RESPONSE_EVT will be returned
3514**
3515** Returns NFC_STATUS_OK if success
3516** NFC_STATUS_NO_BUFFERS if out of buffer
3517** NFC_STATUS_BUSY if busy
3518** NFC_STATUS_FAILED if other error
3519**
3520*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003521tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3522 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003523
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003524 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003525
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003526 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003527 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3528 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003529 return NFC_STATUS_BUSY;
3530 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003531
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003532 if (p_uid) {
3533 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3534 } else {
3535 status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
3536 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003537
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003538 if (status == NFC_STATUS_OK) {
3539 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3540 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003541
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003542 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003543}
3544
3545/*******************************************************************************
3546**
3547** Function RW_I93GetMultiBlockSecurityStatus
3548**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003549** Description This function send Get Multiple Block Security Status
3550** command
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003551**
3552** RW_I93_RESPONSE_EVT will be returned
3553**
3554** Returns NFC_STATUS_OK if success
3555** NFC_STATUS_NO_BUFFERS if out of buffer
3556** NFC_STATUS_BUSY if busy
3557** NFC_STATUS_FAILED if other error
3558**
3559*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003560tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3561 uint16_t number_blocks) {
3562 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003563
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003564 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003565
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003566 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003567 LOG(ERROR) << StringPrintf(
3568 "Unable to start command at state "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003569 "(0x%X)",
3570 rw_cb.tcb.i93.state);
3571 return NFC_STATUS_BUSY;
3572 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003574 status =
3575 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3576 if (status == NFC_STATUS_OK) {
3577 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3578 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003579
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003580 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003581}
3582
3583/*******************************************************************************
3584**
3585** Function RW_I93DetectNDef
3586**
3587** Description This function performs NDEF detection procedure
3588**
3589** RW_I93_NDEF_DETECT_EVT will be returned
3590**
3591** Returns NFC_STATUS_OK if success
3592** NFC_STATUS_FAILED if busy or other error
3593**
3594*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003595tNFC_STATUS RW_I93DetectNDef(void) {
3596 tNFC_STATUS status;
3597 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003598
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003599 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003601 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003602 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3603 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003604 return NFC_STATUS_FAILED;
3605 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003607 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
3608 status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
3609 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3610 } else if ((rw_cb.tcb.i93.num_block == 0) ||
3611 (rw_cb.tcb.i93.block_size == 0)) {
3612 status =
3613 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3614 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003615
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003616 /* clear all flags */
3617 rw_cb.tcb.i93.intl_flags = 0;
3618 } else {
3619 /* read CC in the first block */
3620 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3621 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3622 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003623
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003624 if (status == NFC_STATUS_OK) {
3625 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3626 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05003627
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003628 /* clear flags except flag for 2 bytes of number of blocks */
3629 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3630 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003631
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003632 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003633}
3634
3635/*******************************************************************************
3636**
3637** Function RW_I93ReadNDef
3638**
3639** Description This function performs NDEF read procedure
3640** Note: RW_I93DetectNDef () must be called before using this
3641**
3642** The following event will be returned
3643** RW_I93_NDEF_READ_EVT for each segmented NDEF message
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003644** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3645** complete NDEF
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003646** RW_I93_NDEF_READ_FAIL_EVT for failure
3647**
3648** Returns NFC_STATUS_OK if success
3649** NFC_STATUS_FAILED if I93 is busy or other error
3650**
3651*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003652tNFC_STATUS RW_I93ReadNDef(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003653 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003654
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003655 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003656 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3657 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003658 return NFC_STATUS_FAILED;
3659 }
3660
3661 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
3662 (rw_cb.tcb.i93.ndef_length > 0)) {
3663 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3664 rw_cb.tcb.i93.rw_length = 0;
3665
3666 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
3667 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3668 } else {
3669 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003670 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003671 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003672 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003673 return NFC_STATUS_FAILED;
3674 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003675
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003676 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003677}
3678
3679/*******************************************************************************
3680**
3681** Function RW_I93UpdateNDef
3682**
3683** Description This function performs NDEF update procedure
3684** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003685** Updating data must not be removed until returning
3686** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003687**
3688** The following event will be returned
3689** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3690** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3691**
3692** Returns NFC_STATUS_OK if success
3693** NFC_STATUS_FAILED if I93 is busy or other error
3694**
3695*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003696tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3697 uint16_t block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003698
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003699 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003700
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003701 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003702 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3703 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003704 return NFC_STATUS_FAILED;
3705 }
3706
3707 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3708 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003709 LOG(ERROR) << StringPrintf("NDEF is read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003710 return NFC_STATUS_FAILED;
3711 }
3712 if (rw_cb.tcb.i93.max_ndef_length < length) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003713 LOG(ERROR) << StringPrintf(
3714 "data (%d bytes) is more than max NDEF length "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003715 "(%d)",
3716 length, rw_cb.tcb.i93.max_ndef_length);
3717 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003718 }
3719
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003720 rw_cb.tcb.i93.ndef_length = length;
3721 rw_cb.tcb.i93.p_update_data = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003722
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003723 /* read length field */
3724 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3725 rw_cb.tcb.i93.rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003726
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003727 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003728
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003729 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
3730 NFC_STATUS_OK) {
3731 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3732 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3733 } else {
3734 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003735 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003736 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003737 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003738 return NFC_STATUS_FAILED;
3739 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003740
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003741 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003742}
3743
3744/*******************************************************************************
3745**
3746** Function RW_I93FormatNDef
3747**
3748** Description This function performs formatting procedure
3749**
3750** RW_I93_FORMAT_CPLT_EVT will be returned
3751**
3752** Returns NFC_STATUS_OK if success
3753** NFC_STATUS_FAILED if busy or other error
3754**
3755*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003756tNFC_STATUS RW_I93FormatNDef(void) {
3757 tNFC_STATUS status;
3758 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003759
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003760 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003761
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003762 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003763 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3764 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003765 return NFC_STATUS_FAILED;
3766 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003767
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003768 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
3769 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
3770 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
3771 */
3772 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003773
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003774 /* read blocks with option flag to get block security status */
3775 status = rw_i93_send_cmd_read_single_block(0x0000, true);
3776 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
3777 } else {
3778 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3779 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3780 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003781
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003782 if (status == NFC_STATUS_OK) {
3783 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
3784 rw_cb.tcb.i93.sub_state = sub_state;
3785 rw_cb.tcb.i93.intl_flags = 0;
3786 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003787
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003788 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003789}
3790
3791/*******************************************************************************
3792**
3793** Function RW_I93SetTagReadOnly
3794**
3795** Description This function performs NDEF read-only procedure
3796** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003797** Updating data must not be removed until returning
3798** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003799**
3800** The RW_I93_SET_TAG_RO_EVT event will be returned.
3801**
3802** Returns NFC_STATUS_OK if success
3803** NFC_STATUS_FAILED if I93 is busy or other error
3804**
3805*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003806tNFC_STATUS RW_I93SetTagReadOnly(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003807 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003808
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003809 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003810 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3811 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003812 return NFC_STATUS_FAILED;
3813 }
3814
3815 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3816 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003817 LOG(ERROR) << StringPrintf("NDEF is already read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003818 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003819 }
3820
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003821 /* get CC in the first block */
3822 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
3823 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
3824 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
3825 } else {
3826 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003827 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003828 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003829 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003830 return NFC_STATUS_FAILED;
3831 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003832
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003833 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003834}
3835
3836/*****************************************************************************
3837**
3838** Function RW_I93PresenceCheck
3839**
3840** Description Check if the tag is still in the field.
3841**
3842** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
3843** presence or non-presence.
3844**
3845** Returns NFC_STATUS_OK, if raw data frame sent
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003846** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3847** operation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003848** NFC_STATUS_FAILED: other error
3849**
3850*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003851tNFC_STATUS RW_I93PresenceCheck(void) {
3852 tNFC_STATUS status;
3853 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003854
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003855 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003856
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003857 if (!rw_cb.p_cback) {
3858 return NFC_STATUS_FAILED;
3859 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
3860 evt_data.status = NFC_STATUS_FAILED;
3861 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003862
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003863 return NFC_STATUS_OK;
3864 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3865 return NFC_STATUS_BUSY;
3866 } else {
3867 /* The support of AFI by the VICC is optional, so do not include AFI */
3868 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3869
3870 if (status == NFC_STATUS_OK) {
3871 /* do not retry during presence check */
3872 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
3873 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003874 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003875 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003876
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003877 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003878}
3879
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003880/*******************************************************************************
3881**
3882** Function rw_i93_get_state_name
3883**
3884** Description This function returns the state name.
3885**
3886** NOTE conditionally compiled to save memory.
3887**
3888** Returns pointer to the name
3889**
3890*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003891static std::string rw_i93_get_state_name(uint8_t state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003892 switch (state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003893 case RW_I93_STATE_NOT_ACTIVATED:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003894 return "NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003895 case RW_I93_STATE_IDLE:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003896 return "IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003897 case RW_I93_STATE_BUSY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003898 return "BUSY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003899 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003900 return "NDEF_DETECTION";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003901 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003902 return "READ_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003903 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003904 return "UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003905 case RW_I93_STATE_FORMAT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003906 return "FORMAT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003907 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003908 return "SET_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003909 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003910 return "PRESENCE_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003911 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003912 return "???? UNKNOWN STATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003913 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003914}
3915
3916/*******************************************************************************
3917**
3918** Function rw_i93_get_sub_state_name
3919**
3920** Description This function returns the sub_state name.
3921**
3922** NOTE conditionally compiled to save memory.
3923**
3924** Returns pointer to the name
3925**
3926*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003927static std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003928 switch (sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003929 case RW_I93_SUBSTATE_WAIT_UID:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003930 return "WAIT_UID";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003931 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003932 return "WAIT_SYS_INFO";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003933 case RW_I93_SUBSTATE_WAIT_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003934 return "WAIT_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003935 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003936 return "SEARCH_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003937 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003938 return "CHECK_LOCK_STATUS";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003939 case RW_I93_SUBSTATE_RESET_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003940 return "RESET_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003941 case RW_I93_SUBSTATE_WRITE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003942 return "WRITE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003943 case RW_I93_SUBSTATE_UPDATE_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003944 return "UPDATE_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003945 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003946 return "WAIT_RESET_DSFID_AFI";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003947 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003948 return "CHECK_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003949 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003950 return "WRITE_CC_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003951 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003952 return "WAIT_UPDATE_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003953 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003954 return "LOCK_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003955 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003956 return "WAIT_LOCK_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003957 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003958 return "???? UNKNOWN SUBSTATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003959 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003960}
Evan Chu85b7e842013-01-18 11:02:50 -05003961
3962/*******************************************************************************
3963**
3964** Function rw_i93_get_tag_name
3965**
3966** Description This function returns the tag name.
3967**
3968** NOTE conditionally compiled to save memory.
3969**
3970** Returns pointer to the name
3971**
3972*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003973static std::string rw_i93_get_tag_name(uint8_t product_version) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003974 switch (product_version) {
Evan Chu85b7e842013-01-18 11:02:50 -05003975 case RW_I93_ICODE_SLI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003976 return "SLI/SLIX";
Evan Chu85b7e842013-01-18 11:02:50 -05003977 case RW_I93_ICODE_SLI_S:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003978 return "SLI-S/SLIX-S";
Evan Chu85b7e842013-01-18 11:02:50 -05003979 case RW_I93_ICODE_SLI_L:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003980 return "SLI-L/SLIX-L";
Evan Chu85b7e842013-01-18 11:02:50 -05003981 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003982 return "Tag-it HF-I Plus Inlay";
Evan Chu85b7e842013-01-18 11:02:50 -05003983 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003984 return "Tag-it HF-I Plus Chip";
Evan Chu85b7e842013-01-18 11:02:50 -05003985 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003986 return "Tag-it HF-I Standard Chip/Inlyas";
Evan Chu85b7e842013-01-18 11:02:50 -05003987 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003988 return "Tag-it HF-I Pro Chip/Inlays";
Evan Chu85b7e842013-01-18 11:02:50 -05003989 case RW_I93_STM_LRI1K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003990 return "LRi1K";
Evan Chu85b7e842013-01-18 11:02:50 -05003991 case RW_I93_STM_LRI2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003992 return "LRi2K";
Evan Chu85b7e842013-01-18 11:02:50 -05003993 case RW_I93_STM_LRIS2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003994 return "LRiS2K";
Evan Chu85b7e842013-01-18 11:02:50 -05003995 case RW_I93_STM_LRIS64K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003996 return "LRiS64K";
Evan Chu85b7e842013-01-18 11:02:50 -05003997 case RW_I93_STM_M24LR64_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003998 return "M24LR64";
Evan Chu85b7e842013-01-18 11:02:50 -05003999 case RW_I93_STM_M24LR04E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004000 return "M24LR04E";
Evan Chu85b7e842013-01-18 11:02:50 -05004001 case RW_I93_STM_M24LR16E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004002 return "M24LR16E";
Evan Chu85b7e842013-01-18 11:02:50 -05004003 case RW_I93_STM_M24LR64E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004004 return "M24LR64E";
Raphael Collado867d5c32017-03-27 12:49:40 +02004005 case RW_I93_STM_ST25DV04K:
4006 return "ST25DV04";
4007 case RW_I93_STM_ST25DVHIK:
4008 return "ST25DV";
Evan Chu85b7e842013-01-18 11:02:50 -05004009 case RW_I93_UNKNOWN_PRODUCT:
4010 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004011 return "UNKNOWN";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004012 }
Evan Chu85b7e842013-01-18 11:02:50 -05004013}