blob: acf28a6e58ec284dfdf6824e08ff03bfd2b4fa5e [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 ******************************************************************************/
Ruchi Kandoi6e267b32019-01-24 13:39:18 -080025#include <log/log.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080026#include <string.h>
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080027
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080028#include <android-base/stringprintf.h>
29#include <base/logging.h>
30
31#include "nfc_target.h"
32
33#include "bt_types.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080034#include "nfc_api.h"
35#include "nfc_int.h"
36#include "rw_api.h"
37#include "rw_int.h"
Andre Eisenbach8a4edf62017-11-20 14:51:11 -080038#include "trace_api.h"
39
40using android::base::StringPrintf;
41
42extern bool nfc_debug_enabled;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080043
Ruchi Kandoi46e6e282017-01-30 14:26:10 -080044/* Response timeout */
45#define RW_I93_TOUT_RESP 1000
46/* stay quiet timeout */
47#define RW_I93_TOUT_STAY_QUIET 200
48/* max reading data if read multi block is supported */
49#define RW_I93_READ_MULTI_BLOCK_SIZE 128
50/* CC, zero length NDEF, Terminator TLV */
51#define RW_I93_FORMAT_DATA_LEN 8
52/* max getting lock status if get multi block sec is supported */
53#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
George Changec0e2332019-08-16 20:37:23 +080054/*Capability Container CC Size */
55#define RW_I93_CC_SIZE 4
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080056
57/* main state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080058enum {
59 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
60 RW_I93_STATE_IDLE, /* waiting for upper layer API */
61 RW_I93_STATE_BUSY, /* waiting for response from tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080062
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080063 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
64 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
65 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
66 RW_I93_STATE_FORMAT, /* performing format procedure */
67 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080068
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080069 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080070};
71
72/* sub state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080073enum {
74 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
75 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
76 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
77 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
78 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080079
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080080 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
81 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
82 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080083
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080084 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
85 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
86 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
87 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080088
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080089 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
90 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
91 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080092};
93
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070094static std::string rw_i93_get_state_name(uint8_t state);
95static std::string rw_i93_get_sub_state_name(uint8_t sub_state);
96static std::string rw_i93_get_tag_name(uint8_t product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080097
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080098static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
99 tNFC_CONN* p_data);
100void rw_i93_handle_error(tNFC_STATUS status);
101tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
Raphael Collado867d5c32017-03-27 12:49:40 +0200102tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800103
104/*******************************************************************************
105**
106** Function rw_i93_get_product_version
107**
108** Description Get product version from UID
109**
110** Returns void
111**
112*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800113void rw_i93_get_product_version(uint8_t* p_uid) {
114 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800115
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800116 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
117 return;
118 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800119
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700120 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800121
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800122 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800124 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
125 if (p_uid[2] == I93_UID_ICODE_SLI)
126 p_i93->product_version = RW_I93_ICODE_SLI;
127 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
128 p_i93->product_version = RW_I93_ICODE_SLI_S;
129 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
130 p_i93->product_version = RW_I93_ICODE_SLI_L;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800131 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800132 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
133 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
134 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
135 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
136 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
137 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
138 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
139 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
140 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
141 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
142 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
143 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
144 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
145 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
146 else
147 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
148 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
149 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
150 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
151 p_i93->product_version = RW_I93_STM_M24LR04E_R;
152 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
153 p_i93->product_version = RW_I93_STM_M24LR16E_R;
154 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
155 p_i93->product_version = RW_I93_STM_M24LR64E_R;
Raphael Collado867d5c32017-03-27 12:49:40 +0200156 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DVHIK)
157 p_i93->product_version = RW_I93_STM_ST25DVHIK;
158 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DV04K)
159 p_i93->product_version = RW_I93_STM_ST25DV04K;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800160 else {
161 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
162 case I93_IC_REF_STM_LRI1K:
163 p_i93->product_version = RW_I93_STM_LRI1K;
164 break;
165 case I93_IC_REF_STM_LRI2K:
166 p_i93->product_version = RW_I93_STM_LRI2K;
167 break;
168 case I93_IC_REF_STM_LRIS2K:
169 p_i93->product_version = RW_I93_STM_LRIS2K;
170 break;
171 case I93_IC_REF_STM_LRIS64K:
172 p_i93->product_version = RW_I93_STM_LRIS64K;
173 break;
174 case I93_IC_REF_STM_M24LR64_R:
175 p_i93->product_version = RW_I93_STM_M24LR64_R;
176 break;
177 default:
178 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
179 break;
180 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800181 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800182 } else {
183 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
184 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800185
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700186 DLOG_IF(INFO, nfc_debug_enabled)
187 << StringPrintf("product_version = <%s>",
188 rw_i93_get_tag_name(p_i93->product_version).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800189
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800190 switch (p_i93->product_version) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800191 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
192 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800193 /* these don't support Get System Information Command */
194 /* these support only Inventory, Stay Quiet, Read Single Block, Write
195 * Single Block, Lock Block */
196 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
197 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
198 break;
Evan Chu85b7e842013-01-18 11:02:50 -0500199 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800200 break;
201 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800202}
203
204/*******************************************************************************
205**
Raphael Collado867d5c32017-03-27 12:49:40 +0200206** Function rw_i93_process_ext_sys_info
207**
208** Description Store extended system information of tag
209**
210** Returns FALSE if retrying with protocol extension flag
211**
212*******************************************************************************/
Jack Yu8a86b1f2019-01-30 16:21:45 +0800213bool rw_i93_process_ext_sys_info(uint8_t* p_data, uint16_t length) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200214 uint8_t* p = p_data;
215 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
216 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
217
218 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
219
Jack Yu8a86b1f2019-01-30 16:21:45 +0800220 if (length < (I93_UID_BYTE_LEN + 1)) {
221 android_errorWriteLog(0x534e4554, "122316913");
222 return false;
223 }
224
Raphael Collado867d5c32017-03-27 12:49:40 +0200225 STREAM_TO_UINT8(p_i93->info_flags, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800226 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200227
228 p_uid = uid;
229 STREAM_TO_ARRAY8(p_uid, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800230 length -= I93_UID_BYTE_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200231
232 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800233 if (length < 1) {
234 android_errorWriteLog(0x534e4554, "122316913");
235 return false;
236 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200237 STREAM_TO_UINT8(p_i93->dsfid, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800238 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200239 }
240 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800241 if (length < 1) {
242 android_errorWriteLog(0x534e4554, "122316913");
243 return false;
244 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200245 STREAM_TO_UINT8(p_i93->afi, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800246 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200247 }
248 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800249 if (length < 3) {
250 android_errorWriteLog(0x534e4554, "122316913");
251 return false;
252 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200253 STREAM_TO_UINT16(p_i93->num_block, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800254 length -= I93_INFO_16BIT_NUM_BLOCK_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200255
256 /* it is one less than actual number of bytes */
257 p_i93->num_block += 1;
258
259 STREAM_TO_UINT8(p_i93->block_size, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800260 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200261 /* it is one less than actual number of blocks */
262 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
263 }
264 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800265 if (length < 1) {
266 android_errorWriteLog(0x534e4554, "122316913");
267 return false;
268 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200269 STREAM_TO_UINT8(p_i93->ic_reference, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800270 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200271
272 /* clear existing UID to set product version */
273 p_i93->uid[0] = 0x00;
274
275 /* store UID and get product version */
276 rw_i93_get_product_version(p_uid);
277
278 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
279 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
280 /* STM supports more than 2040 bytes */
281 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
282 }
283 }
284 }
285 return true;
286}
287
288/*******************************************************************************
289**
Evan Chu85b7e842013-01-18 11:02:50 -0500290** Function rw_i93_process_sys_info
291**
292** Description Store system information of tag
293**
294** Returns FALSE if retrying with protocol extension flag
295**
296*******************************************************************************/
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800297bool rw_i93_process_sys_info(uint8_t* p_data, uint16_t length) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800298 uint8_t* p = p_data;
299 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
300 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -0500301
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700302 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500303
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800304 if (length < (I93_UID_BYTE_LEN + 1)) {
305 android_errorWriteLog(0x534e4554, "121259048");
306 return false;
307 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800308 STREAM_TO_UINT8(p_i93->info_flags, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800309 length--;
Evan Chu85b7e842013-01-18 11:02:50 -0500310
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800311 p_uid = uid;
312 STREAM_TO_ARRAY8(p_uid, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800313 length -= I93_UID_BYTE_LEN;
Evan Chu85b7e842013-01-18 11:02:50 -0500314
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800315 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800316 if (length == 0) {
317 android_errorWriteLog(0x534e4554, "121259048");
318 return false;
319 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800320 STREAM_TO_UINT8(p_i93->dsfid, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800321 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800322 }
323 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800324 if (length == 0) {
325 android_errorWriteLog(0x534e4554, "121259048");
326 return false;
327 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800328 STREAM_TO_UINT8(p_i93->afi, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800329 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800330 }
331 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800332 bool block_16_bit = p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK;
333 if (block_16_bit && length > 2) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800334 STREAM_TO_UINT16(p_i93->num_block, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800335 length -= 2;
336 } else if (!block_16_bit && length > 1) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800337 STREAM_TO_UINT8(p_i93->num_block, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800338 length--;
339 } else {
340 android_errorWriteLog(0x534e4554, "121259048");
341 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500342 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800343 /* it is one less than actual number of bytes */
344 p_i93->num_block += 1;
Evan Chu85b7e842013-01-18 11:02:50 -0500345
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800346 STREAM_TO_UINT8(p_i93->block_size, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800347 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800348 /* it is one less than actual number of blocks */
349 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
350 }
351 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800352 if (length == 0) {
353 android_errorWriteLog(0x534e4554, "121259048");
354 return false;
355 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800356 STREAM_TO_UINT8(p_i93->ic_reference, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500357
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800358 /* clear existing UID to set product version */
359 p_i93->uid[0] = 0x00;
Evan Chu85b7e842013-01-18 11:02:50 -0500360
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800361 /* store UID and get product version */
362 rw_i93_get_product_version(p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -0500363
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800364 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
365 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
366 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
367 p_i93->num_block = 8;
368 p_i93->block_size = 4;
369 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
370 /*
371 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
372 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
373 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
374 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
375 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
376 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
377 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
378 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
379 */
380 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
381 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
382 /*
383 ** M24LR16E-R or M24LR64E-R returns system information
384 ** without memory size, if option flag is not set.
385 ** LRIS64K and M24LR64-R return error if option flag is not
386 ** set.
387 */
388 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
389 /* get memory size with protocol extension flag */
390 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
391 NFC_STATUS_OK) {
392 /* STM supports more than 2040 bytes */
393 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
394
395 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500396 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800397 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800398 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
399 (p_i93->ic_reference == 0x21)) {
400 /* workaround of byte order in memory size information */
401 p_i93->num_block = 64;
402 p_i93->block_size = 4;
Raphael Collado867d5c32017-03-27 12:49:40 +0200403 } else if (!(p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)) {
404 if (!(p_i93->intl_flags & RW_I93_FLAG_EXT_COMMANDS)) {
405 if (rw_i93_send_cmd_get_ext_sys_info(NULL) == NFC_STATUS_OK) {
406 /* STM supports more than 2040 bytes */
407 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
408
409 return false;
410 }
411 }
Evan Chu85b7e842013-01-18 11:02:50 -0500412 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800413 }
Evan Chu85b7e842013-01-18 11:02:50 -0500414 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800415 }
Evan Chu85b7e842013-01-18 11:02:50 -0500416
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800417 return true;
Evan Chu85b7e842013-01-18 11:02:50 -0500418}
419
420/*******************************************************************************
421**
422** Function rw_i93_check_sys_info_prot_ext
423**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800424** Description Check if need to set protocol extension flag to get system
425** info
Evan Chu85b7e842013-01-18 11:02:50 -0500426**
427** Returns TRUE if sent Get System Info with protocol extension flag
428**
429*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800430bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
431 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -0500432
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700433 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500434
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800435 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
436 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
437 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
438 (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
439 NFC_STATUS_OK)) {
440 return true;
441 } else {
442 return false;
443 }
Evan Chu85b7e842013-01-18 11:02:50 -0500444}
445
446/*******************************************************************************
447**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800448** Function rw_i93_send_to_upper
449**
450** Description Send response to upper layer
451**
452** Returns void
453**
454*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800455void rw_i93_send_to_upper(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700456 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800457 uint16_t length = p_resp->len;
458 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
459 tRW_DATA rw_data;
460 uint8_t event = RW_I93_MAX_EVT;
461 uint8_t flags;
462 NFC_HDR* p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800463
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700464 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800465
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800466 STREAM_TO_UINT8(flags, p);
467 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800468
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800469 if (flags & I93_FLAG_ERROR_DETECTED) {
470 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
471 /* getting system info with protocol extension flag */
472 /* This STM tag supports more than 2040 bytes */
473 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
474 p_i93->state = RW_I93_STATE_BUSY;
475 } else {
476 /* notify error to upper layer */
477 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
478 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
479 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800480
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800481 rw_cb.tcb.i93.sent_cmd = 0;
482 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800483 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800484 return;
485 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800486
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800487 switch (p_i93->sent_cmd) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800488 case I93_CMD_INVENTORY:
489
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800490 /* forward inventory response */
491 rw_data.i93_inventory.status = NFC_STATUS_OK;
492 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800493
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800494 p_uid = rw_data.i93_inventory.uid;
495 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800496
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800497 /* store UID and get product version */
498 rw_i93_get_product_version(p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800499
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800500 event = RW_I93_INVENTORY_EVT;
501 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800502
503 case I93_CMD_READ_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200504 case I93_CMD_EXT_READ_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800505 case I93_CMD_READ_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200506 case I93_CMD_EXT_READ_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800507 case I93_CMD_GET_MULTI_BLK_SEC:
Raphael Collado867d5c32017-03-27 12:49:40 +0200508 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800509
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800510 /* forward tag data or security status */
511 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800512
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800513 if (p_buff) {
514 p_buff->offset = 0;
515 p_buff->len = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800516
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800517 memcpy((p_buff + 1), p, length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800518
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800519 rw_data.i93_data.status = NFC_STATUS_OK;
520 rw_data.i93_data.command = p_i93->sent_cmd;
521 rw_data.i93_data.p_data = p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800522
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800523 event = RW_I93_DATA_EVT;
524 } else {
525 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
526 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
527 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800528
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800529 event = RW_I93_CMD_CMPL_EVT;
530 }
531 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800532
533 case I93_CMD_WRITE_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200534 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800535 case I93_CMD_LOCK_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200536 case I93_CMD_EXT_LOCK_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800537 case I93_CMD_WRITE_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200538 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800539 case I93_CMD_SELECT:
540 case I93_CMD_RESET_TO_READY:
541 case I93_CMD_WRITE_AFI:
542 case I93_CMD_LOCK_AFI:
543 case I93_CMD_WRITE_DSFID:
544 case I93_CMD_LOCK_DSFID:
545
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800546 /* notify the complete of command */
547 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
548 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
549 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800550
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800551 event = RW_I93_CMD_CMPL_EVT;
552 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800553
554 case I93_CMD_GET_SYS_INFO:
555
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800556 if (rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800557 rw_data.i93_sys_info.status = NFC_STATUS_OK;
558 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
559 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
560 rw_data.i93_sys_info.afi = p_i93->afi;
561 rw_data.i93_sys_info.num_block = p_i93->num_block;
562 rw_data.i93_sys_info.block_size = p_i93->block_size;
563 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
Evan Chu85b7e842013-01-18 11:02:50 -0500564
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800565 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
Evan Chu85b7e842013-01-18 11:02:50 -0500566
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800567 event = RW_I93_SYS_INFO_EVT;
568 } else {
569 /* retrying with protocol extension flag */
570 p_i93->state = RW_I93_STATE_BUSY;
571 return;
572 }
573 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800574
Raphael Collado867d5c32017-03-27 12:49:40 +0200575 case I93_CMD_EXT_GET_SYS_INFO:
576
Jack Yu8a86b1f2019-01-30 16:21:45 +0800577 if (rw_i93_process_ext_sys_info(p, length)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200578 rw_data.i93_sys_info.status = NFC_STATUS_OK;
579 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
580 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
581 rw_data.i93_sys_info.afi = p_i93->afi;
582 rw_data.i93_sys_info.num_block = p_i93->num_block;
583 rw_data.i93_sys_info.block_size = p_i93->block_size;
584 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
585
586 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
587
588 event = RW_I93_SYS_INFO_EVT;
589 } else {
590 /* retrying with protocol extension flag or with extended sys info
591 * command */
592 p_i93->state = RW_I93_STATE_BUSY;
593 return;
594 }
595 break;
596
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800597 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800598 break;
599 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800600
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800601 rw_cb.tcb.i93.sent_cmd = 0;
602 if (event != RW_I93_MAX_EVT) {
603 (*(rw_cb.p_cback))(event, &rw_data);
604 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700605 LOG(ERROR) << StringPrintf("Invalid response");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800606 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800607}
608
609/*******************************************************************************
610**
611** Function rw_i93_send_to_lower
612**
613** Description Send Request frame to lower layer
614**
615** Returns TRUE if success
616**
617*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800618bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800619 /* store command for retransmitting */
620 if (rw_cb.tcb.i93.p_retry_cmd) {
621 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
622 rw_cb.tcb.i93.p_retry_cmd = NULL;
623 }
Evan Chu85b7e842013-01-18 11:02:50 -0500624
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800625 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
Evan Chu85b7e842013-01-18 11:02:50 -0500626
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800627 if (rw_cb.tcb.i93.p_retry_cmd) {
628 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
629 sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
630 }
Evan Chu85b7e842013-01-18 11:02:50 -0500631
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800632 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700633 LOG(ERROR) << StringPrintf("failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800634 return false;
635 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800636
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800637 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
638 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800639
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800640 return true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800641}
642
643/*******************************************************************************
644**
645** Function rw_i93_send_cmd_inventory
646**
647** Description Send Inventory Request to VICC
648**
649** Returns tNFC_STATUS
650**
651*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800652tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
653 uint8_t afi) {
654 NFC_HDR* p_cmd;
655 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800656
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700657 DLOG_IF(INFO, nfc_debug_enabled)
658 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800659
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800660 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800661
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800662 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700663 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800664 return NFC_STATUS_NO_BUFFERS;
665 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800666
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800667 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
668 p_cmd->len = 3;
669 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800670
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800671 /* Flags */
672 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
673 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
674 if (including_afi) {
675 flags |= I93_FLAG_AFI_PRESENT;
676 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800678 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800679
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800680 /* Command Code */
681 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800683 if (including_afi) {
684 /* Parameters */
685 UINT8_TO_STREAM(p, afi); /* Optional AFI */
686 p_cmd->len++;
687 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700688
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800689 if (p_uid) {
690 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
691 ARRAY8_TO_STREAM(p, p_uid); /* UID */
692 p_cmd->len += I93_UID_BYTE_LEN;
693 } else {
694 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
695 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800696
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800697 if (rw_i93_send_to_lower(p_cmd)) {
698 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
699 return NFC_STATUS_OK;
700 } else {
701 return NFC_STATUS_FAILED;
702 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800703}
704
705/*******************************************************************************
706**
707** Function rw_i93_send_cmd_stay_quiet
708**
709** Description Send Stay Quiet Request to VICC
710**
711** Returns tNFC_STATUS
712**
713*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800714tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
715 NFC_HDR* p_cmd;
716 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800717
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700718 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800719
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800720 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800721
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800722 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700723 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800724 return NFC_STATUS_NO_BUFFERS;
725 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800726
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800727 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
728 p_cmd->len = 10;
729 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800730
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800731 /* Flags */
732 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
733 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800734
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800735 /* Command Code */
736 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800737
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800738 /* Parameters */
739 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800740
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800741 if (rw_i93_send_to_lower(p_cmd)) {
742 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800743
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800744 /* restart timer for stay quiet */
745 nfc_start_quick_timer(
746 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
747 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
748 return NFC_STATUS_OK;
749 } else {
750 return NFC_STATUS_FAILED;
751 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800752}
753
754/*******************************************************************************
755**
756** Function rw_i93_send_cmd_read_single_block
757**
758** Description Send Read Single Block Request to VICC
759**
760** Returns tNFC_STATUS
761**
762*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800763tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
764 bool read_security) {
765 NFC_HDR* p_cmd;
766 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800767
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700768 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800770 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800771
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800772 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700773 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800774 return NFC_STATUS_NO_BUFFERS;
775 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800776
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800777 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
778 p_cmd->len = 11;
779 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800780
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800781 /* Flags */
782 flags =
783 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800785 if (read_security) flags |= I93_FLAG_OPTION_SET;
Evan Chu85b7e842013-01-18 11:02:50 -0500786
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800787 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
788 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800790 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800791
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800792 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200793 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
794 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_SINGLE_BLOCK);
795 } else {
796 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
797 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800798
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800799 /* Parameters */
800 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500801
Raphael Collado867d5c32017-03-27 12:49:40 +0200802 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
803 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800804 UINT16_TO_STREAM(p, block_number); /* Block number */
805 p_cmd->len++;
806 } else {
807 UINT8_TO_STREAM(p, block_number); /* Block number */
808 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800809
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800810 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200811 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
812 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_SINGLE_BLOCK;
813 else
814 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800815 return NFC_STATUS_OK;
816 } else {
817 return NFC_STATUS_FAILED;
818 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800819}
820
821/*******************************************************************************
822**
823** Function rw_i93_send_cmd_write_single_block
824**
825** Description Send Write Single Block Request to VICC
826**
827** Returns tNFC_STATUS
828**
829*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800830tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
831 uint8_t* p_data) {
832 NFC_HDR* p_cmd;
833 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800834
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700835 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800836
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800837 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800838
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800839 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700840 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800841 return NFC_STATUS_NO_BUFFERS;
842 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800843
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800844 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
845 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
846 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800847
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800848 /* Flags */
849 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
850 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
851 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
852 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
853 /* Option must be set for TI tag */
854 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
855 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
856 } else {
857 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
858 RW_I93_FLAG_DATA_RATE);
859 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800860
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800861 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
862 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500863
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800864 UINT8_TO_STREAM(p, flags);
Evan Chu85b7e842013-01-18 11:02:50 -0500865
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800866 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200867 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
868 UINT8_TO_STREAM(p, I93_CMD_EXT_WRITE_SINGLE_BLOCK);
869 } else {
870 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
871 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800872
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800873 /* Parameters */
874 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500875
Raphael Collado867d5c32017-03-27 12:49:40 +0200876 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
877 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800878 UINT16_TO_STREAM(p, block_number); /* Block number */
879 p_cmd->len++;
880 } else {
881 UINT8_TO_STREAM(p, block_number); /* Block number */
882 }
Evan Chu85b7e842013-01-18 11:02:50 -0500883
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800884 /* Data */
885 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800886
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800887 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200888 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
889 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_SINGLE_BLOCK;
890 else
891 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800892 return NFC_STATUS_OK;
893 } else {
894 return NFC_STATUS_FAILED;
895 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800896}
897
898/*******************************************************************************
899**
900** Function rw_i93_send_cmd_lock_block
901**
902** Description Send Lock Block Request to VICC
903**
Evan Chu85b7e842013-01-18 11:02:50 -0500904** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
905** do not support.
906**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800907** Returns tNFC_STATUS
908**
909*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800910tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
911 NFC_HDR* p_cmd;
912 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800913
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700914 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800915
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800916 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800917
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800918 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700919 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800920 return NFC_STATUS_NO_BUFFERS;
921 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800922
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800923 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
924 p_cmd->len = 11;
925 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800926
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800927 /* Flags */
928 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
929 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
930 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
931 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
932 /* Option must be set for TI tag */
933 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
934 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
935 } else {
936 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
937 RW_I93_FLAG_DATA_RATE));
938 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800939
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800940 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200941 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
942 UINT8_TO_STREAM(p, I93_CMD_EXT_LOCK_BLOCK);
943 } else {
944 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
945 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800946
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800947 /* Parameters */
948 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +0200949
950 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
951 UINT16_TO_STREAM(p, block_number); /* Block number */
952 p_cmd->len++;
953 } else {
954 UINT8_TO_STREAM(p, block_number); /* Block number */
955 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800956
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800957 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200958 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
959 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_LOCK_BLOCK;
960 else
961 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800962 return NFC_STATUS_OK;
963 } else {
964 return NFC_STATUS_FAILED;
965 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800966}
967
968/*******************************************************************************
969**
970** Function rw_i93_send_cmd_read_multi_blocks
971**
972** Description Send Read Multiple Blocks Request to VICC
973**
974** Returns tNFC_STATUS
975**
976*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800977tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
978 uint16_t number_blocks) {
979 NFC_HDR* p_cmd;
980 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800981
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700982 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800983
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800984 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800985
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800986 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700987 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800988 return NFC_STATUS_NO_BUFFERS;
989 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800990
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800991 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
992 p_cmd->len = 12;
993 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800994
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800995 /* Flags */
996 flags =
997 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500998
Raphael Collado867d5c32017-03-27 12:49:40 +0200999 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001000 flags |= I93_FLAG_PROT_EXT_YES;
Raphael Collado867d5c32017-03-27 12:49:40 +02001001 }
Evan Chu85b7e842013-01-18 11:02:50 -05001002
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001003 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001004
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001005 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001006 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1007 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_MULTI_BLOCK);
1008 } else {
1009 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
1010 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001011
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001012 /* Parameters */
1013 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001014
Raphael Collado867d5c32017-03-27 12:49:40 +02001015 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1016 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001017 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1018 p_cmd->len++;
1019 } else {
1020 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1021 }
Evan Chu85b7e842013-01-18 11:02:50 -05001022
Raphael Collado867d5c32017-03-27 12:49:40 +02001023 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1024 UINT16_TO_STREAM(
1025 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1026 p_cmd->len++;
1027 } else {
1028 UINT8_TO_STREAM(
1029 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1030 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001031
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001032 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001033 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1034 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_MULTI_BLOCK;
1035 else
1036 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001037 return NFC_STATUS_OK;
1038 } else {
1039 return NFC_STATUS_FAILED;
1040 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001041}
1042
1043/*******************************************************************************
1044**
1045** Function rw_i93_send_cmd_write_multi_blocks
1046**
1047** Description Send Write Multiple Blocks Request to VICC
1048**
1049** Returns tNFC_STATUS
1050**
1051*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02001052tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001053 uint16_t number_blocks,
1054 uint8_t* p_data) {
1055 NFC_HDR* p_cmd;
1056 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001057
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001058 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001059
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001060 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001061
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001062 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001063 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001064 return NFC_STATUS_NO_BUFFERS;
1065 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001066
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001067 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1068 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
1069 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001070
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001071 /* Flags */
1072 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1073 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001074
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001075 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001076 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1077 INT8_TO_STREAM(p, I93_CMD_EXT_WRITE_MULTI_BLOCK);
1078 } else {
1079 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
1080 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001081
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001082 /* Parameters */
1083 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +02001084 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1085 UINT16_TO_STREAM(p, first_block_number); /* Block number */
1086 UINT16_TO_STREAM(
1087 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1088 p_cmd->len += 2;
1089 } else {
1090 UINT8_TO_STREAM(p, first_block_number); /* Block number */
1091 UINT8_TO_STREAM(
1092 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1093 }
1094
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001095 UINT8_TO_STREAM(
1096 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001097
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001098 /* Data */
1099 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001100
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001101 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001102 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1103 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_MULTI_BLOCK;
1104 else
1105 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001106 return NFC_STATUS_OK;
1107 } else {
1108 return NFC_STATUS_FAILED;
1109 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001110}
1111
1112/*******************************************************************************
1113**
1114** Function rw_i93_send_cmd_select
1115**
1116** Description Send Select Request to VICC
1117**
1118** Returns tNFC_STATUS
1119**
1120*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001121tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1122 NFC_HDR* p_cmd;
1123 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001124
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001125 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001126
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001127 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001128
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001129 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001130 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001131 return NFC_STATUS_NO_BUFFERS;
1132 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001133
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001134 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1135 p_cmd->len = 10;
1136 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001137
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001138 /* Flags */
1139 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1140 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001141
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001142 /* Command Code */
1143 UINT8_TO_STREAM(p, I93_CMD_SELECT);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001144
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001145 /* Parameters */
1146 ARRAY8_TO_STREAM(p, p_uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001147
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001148 if (rw_i93_send_to_lower(p_cmd)) {
1149 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1150 return NFC_STATUS_OK;
1151 } else {
1152 return NFC_STATUS_FAILED;
1153 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001154}
1155
1156/*******************************************************************************
1157**
1158** Function rw_i93_send_cmd_reset_to_ready
1159**
1160** Description Send Reset to Ready Request to VICC
1161**
1162** Returns tNFC_STATUS
1163**
1164*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001165tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1166 NFC_HDR* p_cmd;
1167 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001168
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001169 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001170
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001171 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001172
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001173 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001174 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001175 return NFC_STATUS_NO_BUFFERS;
1176 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001177
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001178 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1179 p_cmd->len = 10;
1180 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001181
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001182 /* Flags */
1183 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1184 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001185
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001186 /* Command Code */
1187 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001189 /* Parameters */
1190 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001191
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001192 if (rw_i93_send_to_lower(p_cmd)) {
1193 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1194 return NFC_STATUS_OK;
1195 } else {
1196 return NFC_STATUS_FAILED;
1197 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001198}
1199
1200/*******************************************************************************
1201**
1202** Function rw_i93_send_cmd_write_afi
1203**
1204** Description Send Write AFI Request to VICC
1205**
1206** Returns tNFC_STATUS
1207**
1208*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001209tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1210 NFC_HDR* p_cmd;
1211 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001212
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001213 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001214
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001215 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001216
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001217 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001218 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001219 return NFC_STATUS_NO_BUFFERS;
1220 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001221
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001222 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1223 p_cmd->len = 11;
1224 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001225
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001226 /* Flags */
1227 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1228 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001230 /* Command Code */
1231 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001232
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001233 /* Parameters */
1234 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1235 UINT8_TO_STREAM(p, afi); /* AFI */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001236
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001237 if (rw_i93_send_to_lower(p_cmd)) {
1238 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1239 return NFC_STATUS_OK;
1240 } else {
1241 return NFC_STATUS_FAILED;
1242 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001243}
1244
1245/*******************************************************************************
1246**
1247** Function rw_i93_send_cmd_lock_afi
1248**
1249** Description Send Lock AFI Request to VICC
1250**
1251** Returns tNFC_STATUS
1252**
1253*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001254tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1255 NFC_HDR* p_cmd;
1256 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001257
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001258 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001260 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001261
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001262 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001263 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001264 return NFC_STATUS_NO_BUFFERS;
1265 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001266
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001267 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1268 p_cmd->len = 10;
1269 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001270
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001271 /* Flags */
1272 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1273 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001274
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001275 /* Command Code */
1276 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001277
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001278 /* Parameters */
1279 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001280
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001281 if (rw_i93_send_to_lower(p_cmd)) {
1282 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1283 return NFC_STATUS_OK;
1284 } else {
1285 return NFC_STATUS_FAILED;
1286 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001287}
1288
1289/*******************************************************************************
1290**
1291** Function rw_i93_send_cmd_write_dsfid
1292**
1293** Description Send Write DSFID Request to VICC
1294**
1295** Returns tNFC_STATUS
1296**
1297*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001298tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1299 NFC_HDR* p_cmd;
1300 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001301
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001302 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001304 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001305
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001306 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001307 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001308 return NFC_STATUS_NO_BUFFERS;
1309 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001310
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001311 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1312 p_cmd->len = 11;
1313 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001314
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001315 /* Flags */
1316 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1317 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001318
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001319 /* Command Code */
1320 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001321
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001322 /* Parameters */
1323 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1324 UINT8_TO_STREAM(p, dsfid); /* DSFID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001325
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001326 if (rw_i93_send_to_lower(p_cmd)) {
1327 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1328 return NFC_STATUS_OK;
1329 } else {
1330 return NFC_STATUS_FAILED;
1331 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001332}
1333
1334/*******************************************************************************
1335**
1336** Function rw_i93_send_cmd_lock_dsfid
1337**
1338** Description Send Lock DSFID Request to VICC
1339**
1340** Returns tNFC_STATUS
1341**
1342*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001343tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1344 NFC_HDR* p_cmd;
1345 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001346
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001347 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001348
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001349 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001350
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001351 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001352 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001353 return NFC_STATUS_NO_BUFFERS;
1354 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001355
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001356 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1357 p_cmd->len = 10;
1358 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001359
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001360 /* Flags */
1361 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1362 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001363
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001364 /* Command Code */
1365 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001366
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001367 /* Parameters */
1368 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001369
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001370 if (rw_i93_send_to_lower(p_cmd)) {
1371 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1372 return NFC_STATUS_OK;
1373 } else {
1374 return NFC_STATUS_FAILED;
1375 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001376}
1377
1378/*******************************************************************************
1379**
Raphael Collado867d5c32017-03-27 12:49:40 +02001380** Function rw_i93_send_cmd_get_ext_sys_info
1381**
1382** Description Send Get Extended System Information Request to VICC
1383**
1384** Returns tNFC_STATUS
1385**
1386*******************************************************************************/
1387tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid) {
1388 NFC_HDR* p_cmd;
1389 uint8_t* p;
1390
1391 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1392
1393 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1394
1395 if (!p_cmd) {
1396 DLOG_IF(INFO, nfc_debug_enabled) << __func__ << "Cannot allocate buffer";
1397 return NFC_STATUS_NO_BUFFERS;
1398 }
1399
1400 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1401 p_cmd->len = 11;
1402 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1403
1404 /* Flags */
1405 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1406 RW_I93_FLAG_DATA_RATE));
1407
1408 /* Command Code */
1409 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_SYS_INFO);
1410
1411 /* Parameters request field */
1412 UINT8_TO_STREAM(p,
1413 (I93_INFO_FLAG_MOI | I93_INFO_FLAG_DSFID | I93_INFO_FLAG_AFI |
1414 I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_IC_REF));
1415
1416 /* Parameters */
1417 if (p_uid) {
1418 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1419 } else {
1420 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1421 }
1422
1423 if (rw_i93_send_to_lower(p_cmd)) {
1424 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_SYS_INFO;
1425 return NFC_STATUS_OK;
1426 } else {
1427 return NFC_STATUS_FAILED;
1428 }
1429}
1430
1431/*******************************************************************************
1432**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001433** Function rw_i93_send_cmd_get_sys_info
1434**
1435** Description Send Get System Information Request to VICC
1436**
1437** Returns tNFC_STATUS
1438**
1439*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001440tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1441 NFC_HDR* p_cmd;
1442 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001443
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001444 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001445
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001446 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001447
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001448 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001449 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001450 return NFC_STATUS_NO_BUFFERS;
1451 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001452
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001453 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1454 p_cmd->len = 10;
1455 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001456
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001457 /* Flags */
1458 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1459 RW_I93_FLAG_DATA_RATE | extra_flags));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001460
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001461 /* Command Code */
1462 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001463
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001464 /* Parameters */
1465 if (p_uid) {
1466 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1467 } else {
1468 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
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)) {
1472 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1473 return NFC_STATUS_OK;
1474 } else {
1475 return NFC_STATUS_FAILED;
1476 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001477}
1478
1479/*******************************************************************************
1480**
1481** Function rw_i93_send_cmd_get_multi_block_sec
1482**
1483** Description Send Get Multiple Block Security Status Request to VICC
1484**
1485** Returns tNFC_STATUS
1486**
1487*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001488tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1489 uint16_t number_blocks) {
1490 NFC_HDR* p_cmd;
1491 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001492
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001493 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001494
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001495 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001496
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001497 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001498 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001499 return NFC_STATUS_NO_BUFFERS;
1500 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001501
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001502 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1503 p_cmd->len = 12;
1504 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001505
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001506 /* Flags */
1507 flags =
1508 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -05001509
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001510 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1511 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -05001512
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001513 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001514
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001515 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001516 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1517 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_MULTI_BLK_SEC);
1518 } else {
1519 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1520 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001521
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001522 /* Parameters */
1523 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001524
Raphael Collado867d5c32017-03-27 12:49:40 +02001525 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1526 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001527 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1528 UINT16_TO_STREAM(
1529 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1530 p_cmd->len += 2;
1531 } else {
1532 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1533 UINT8_TO_STREAM(
1534 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1535 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001536
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001537 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001538 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1539 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_MULTI_BLK_SEC;
1540 else
1541 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001542 return NFC_STATUS_OK;
1543 } else {
1544 return NFC_STATUS_FAILED;
1545 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001546}
1547
1548/*******************************************************************************
1549**
1550** Function rw_i93_get_next_blocks
1551**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001552** Description Read as many blocks as possible (up to
1553** RW_I93_READ_MULTI_BLOCK_SIZE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001554**
1555** Returns tNFC_STATUS
1556**
1557*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001558tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1559 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1560 uint16_t first_block;
1561 uint16_t num_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001562
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001563 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001564
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001565 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001566
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001567 /* more blocks, more efficent but more error rate */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001568
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001569 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1570 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001571
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001572 if (num_block + first_block > p_i93->num_block)
1573 num_block = p_i93->num_block - first_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001574
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001575 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
1576 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1577 ** - The max number of blocks is 32 and they are all located in the
1578 ** same sector.
1579 ** - The sector is 32 blocks of 4 bytes.
1580 */
1581 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1582 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1583 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1584 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
1585 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1586 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1587 num_block = I93_STM_MAX_BLOCKS_PER_READ;
Evan Chu85b7e842013-01-18 11:02:50 -05001588
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001589 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1590 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1591 num_block = I93_STM_BLOCKS_PER_SECTOR -
1592 (first_block % I93_STM_BLOCKS_PER_SECTOR);
Evan Chu85b7e842013-01-18 11:02:50 -05001593 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001594 }
1595 }
Evan Chu85b7e842013-01-18 11:02:50 -05001596
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001597 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1598 } else {
1599 return rw_i93_send_cmd_read_single_block(first_block, false);
1600 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001601}
1602
1603/*******************************************************************************
1604**
Evan Chu85b7e842013-01-18 11:02:50 -05001605** Function rw_i93_get_next_block_sec
1606**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001607** Description Get as many security of blocks as possible from
1608** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
Evan Chu85b7e842013-01-18 11:02:50 -05001609**
1610** Returns tNFC_STATUS
1611**
1612*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001613tNFC_STATUS rw_i93_get_next_block_sec(void) {
1614 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1615 uint16_t num_blocks;
Evan Chu85b7e842013-01-18 11:02:50 -05001616
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001617 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001618
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001619 if (p_i93->num_block <= p_i93->rw_offset) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001620 LOG(ERROR) << StringPrintf(
1621 "rw_offset(0x%x) must be less than num_block(0x%x)", p_i93->rw_offset,
1622 p_i93->num_block);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001623 return NFC_STATUS_FAILED;
1624 }
Evan Chu85b7e842013-01-18 11:02:50 -05001625
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001626 num_blocks = p_i93->num_block - p_i93->rw_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001627
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001628 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1629 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
Evan Chu85b7e842013-01-18 11:02:50 -05001630
Raphael Collado867d5c32017-03-27 12:49:40 +02001631 DLOG_IF(INFO, nfc_debug_enabled)
1632 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001633 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
Evan Chu85b7e842013-01-18 11:02:50 -05001634}
1635
1636/*******************************************************************************
1637**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001638** Function rw_i93_sm_detect_ndef
1639**
1640** Description Process NDEF detection procedure
1641**
1642** 1. Get UID if not having yet
1643** 2. Get System Info if not having yet
1644** 3. Read first block for CC
1645** 4. Search NDEF Type and length
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001646** 5. Get block status to get max NDEF size and read-only
1647** status
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001648**
1649** Returns void
1650**
1651*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001652void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001653 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001654 uint8_t flags, u8 = 0, cc[4];
1655 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1656 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1657 tRW_DATA rw_data;
1658 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001659
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001660 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1661 "sub_state:%s (0x%x)",
1662 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 -08001663
Ruchi Kandoi6e267b32019-01-24 13:39:18 -08001664 if (length == 0) {
1665 android_errorWriteLog(0x534e4554, "121260197");
1666 rw_i93_handle_error(NFC_STATUS_FAILED);
1667 return;
1668 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001669 STREAM_TO_UINT8(flags, p);
1670 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001671
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001672 if (flags & I93_FLAG_ERROR_DETECTED) {
1673 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1674 /* getting system info with protocol extension flag */
1675 /* This STM tag supports more than 2040 bytes */
1676 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1677 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001678 DLOG_IF(INFO, nfc_debug_enabled)
1679 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001680 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001681 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001682 return;
1683 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001684
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001685 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001686 case RW_I93_SUBSTATE_WAIT_UID:
1687
Ruchi Kandoi6e267b32019-01-24 13:39:18 -08001688 if (length < (I93_UID_BYTE_LEN + 1)) {
1689 android_errorWriteLog(0x534e4554, "121260197");
1690 rw_i93_handle_error(NFC_STATUS_FAILED);
1691 return;
1692 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001693 STREAM_TO_UINT8(u8, p); /* DSFID */
1694 p_uid = p_i93->uid;
1695 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001696
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001697 if (u8 != I93_DFS_UNSUPPORTED) {
1698 /* if Data Storage Format is unknown */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001699 DLOG_IF(INFO, nfc_debug_enabled)
1700 << StringPrintf("Got unknown DSFID (0x%02x)", u8);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001701 rw_i93_handle_error(NFC_STATUS_FAILED);
1702 } else {
1703 /* get system information to get memory size */
1704 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
1705 NFC_STATUS_OK) {
1706 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1707 } else {
1708 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001709 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001710 }
1711 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001712
1713 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1714
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001715 p_i93->block_size = 0;
1716 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001717
Ruchi Kandoiba95bb12019-01-24 14:45:55 -08001718 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001719 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001720 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001721 }
1722
1723 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001724 DLOG_IF(INFO, nfc_debug_enabled)
1725 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001726 rw_i93_handle_error(status);
1727 } else {
1728 /* read CC in the first block */
1729 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1730 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1731 } else {
1732 rw_i93_handle_error(NFC_STATUS_FAILED);
1733 }
1734 }
1735 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001736
1737 case RW_I93_SUBSTATE_WAIT_CC:
1738
George Changec0e2332019-08-16 20:37:23 +08001739 if (length < RW_I93_CC_SIZE) {
1740 android_errorWriteLog(0x534e4554, "139188579");
1741 rw_i93_handle_error(NFC_STATUS_FAILED);
1742 return;
1743 }
1744
1745 /* assume block size is more than RW_I93_CC_SIZE 4 */
1746 STREAM_TO_ARRAY(cc, p, RW_I93_CC_SIZE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001747
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001748 status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001749
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001750 /*
1751 ** Capability Container (CC)
1752 **
1753 ** CC[0] : magic number (0xE1)
1754 ** CC[1] : Bit 7-6:Major version number
1755 ** : Bit 5-4:Minor version number
1756 ** : Bit 3-2:Read access condition (00b: read access granted
1757 ** without any security)
1758 ** : Bit 1-0:Write access condition (00b: write access granted
1759 ** without any security)
1760 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
1761 ** 0xFF if more than 2040bytes]
1762 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1763 ** : Bit 1:Inventory page read is supported [NXP]
1764 ** : Bit 2:More than 2040 bytes are supported [STM]
1765 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001766
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001767 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1768 "cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
1769 DLOG_IF(INFO, nfc_debug_enabled)
1770 << StringPrintf("Total blocks:0x%04X, Block size:0x%02X",
1771 p_i93->num_block, p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001772
Raphael Collado867d5c32017-03-27 12:49:40 +02001773 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1774 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001775 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1776 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1777 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1778 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1779 /* read-only or password required to write */
1780 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1781 }
1782 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
1783 /* tag supports read multi blocks command */
1784 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1785 }
Raphael Collado867d5c32017-03-27 12:49:40 +02001786 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1787 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1788 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001789 status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001790 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001791 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001792
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001793 if (status == NFC_STATUS_OK) {
1794 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1795 */
1796 if (cc[2] != 0)
1797 p_i93->rw_offset = 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001798 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001799 p_i93->rw_offset = 8;
1800
1801 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1802 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1803 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1804 } else {
1805 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001806 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001807 } else {
1808 rw_i93_handle_error(NFC_STATUS_FAILED);
1809 }
1810 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001811
1812 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1813
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001814 /* search TLV within read blocks */
1815 for (xx = 0; xx < length; xx++) {
1816 /* if looking for type */
1817 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1818 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1819 continue;
1820 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1821 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1822 /* store found type and get length field */
1823 p_i93->tlv_type = *(p + xx);
1824 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001825
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001826 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1827 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1828 /* no NDEF TLV found */
1829 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1830 break;
1831 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001832 DLOG_IF(INFO, nfc_debug_enabled)
1833 << StringPrintf("Invalid type: 0x%02x", *(p + xx));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001834 rw_i93_handle_error(NFC_STATUS_FAILED);
1835 return;
1836 }
1837 } else if (p_i93->tlv_detect_state ==
1838 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
1839 /* if 3 bytes length field */
1840 if (*(p + xx) == 0xFF) {
1841 /* need 2 more bytes for length field */
1842 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1843 } else {
1844 p_i93->tlv_length = *(p + xx);
1845 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1846
1847 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1848 p_i93->ndef_tlv_last_offset =
1849 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1850 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001851 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001852 }
1853 } else if (p_i93->tlv_detect_state ==
1854 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
1855 /* the second byte of 3 bytes length field */
1856 p_i93->tlv_length = *(p + xx);
1857 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1858 } else if (p_i93->tlv_detect_state ==
1859 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
1860 /* the last byte of 3 bytes length field */
1861 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
1862 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001863
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001864 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1865 p_i93->ndef_tlv_last_offset =
1866 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1867 break;
1868 }
1869 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
1870 /* this is other than NDEF TLV */
1871 if (p_i93->tlv_length <= length - xx) {
1872 /* skip value field */
1873 xx += (uint8_t)p_i93->tlv_length;
1874 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1875 } else {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001876 /* read more data */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001877 p_i93->tlv_length -= (length - xx);
1878 break;
1879 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001880 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001881 }
1882
1883 /* found NDEF TLV and read length field */
1884 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
1885 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
1886 p_i93->ndef_length = p_i93->tlv_length;
1887
1888 /* get lock status to see if read-only */
1889 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1890 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1891 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1892 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1893 /* these doesn't support GetMultiBlockSecurityStatus */
1894
1895 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
1896 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
1897
1898 /* read block to get lock status */
1899 rw_i93_send_cmd_read_single_block(first_block, true);
1900 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1901 } else {
1902 /* block offset for read-only check */
1903 p_i93->rw_offset = 0;
1904
1905 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
1906 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1907 } else {
1908 rw_i93_handle_error(NFC_STATUS_FAILED);
1909 }
1910 }
1911 } else {
1912 /* read more data */
1913 p_i93->rw_offset += length;
1914
1915 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
1916 rw_i93_handle_error(NFC_STATUS_FAILED);
1917 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1918 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1919 } else {
1920 rw_i93_handle_error(NFC_STATUS_FAILED);
1921 }
1922 }
1923 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001924
1925 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1926
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001927 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1928 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1929 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1930 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1931 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001932
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001933 block = (p_i93->rw_offset / p_i93->block_size);
1934 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001935
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001936 if ((*p) & I93_BLOCK_LOCKED) {
1937 if (block <= last_block) {
1938 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1939 }
1940 } else {
1941 /* if we need to check more user blocks */
1942 if (block + 1 < p_i93->num_block) {
1943 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001944
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001945 /* read block to get lock status */
1946 rw_i93_send_cmd_read_single_block(
1947 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
1948 break;
1949 }
Evan Chu85b7e842013-01-18 11:02:50 -05001950 }
1951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001952 p_i93->max_ndef_length =
1953 p_i93->ndef_length
1954 /* add available bytes including the last block of NDEF TLV */
1955 + (p_i93->block_size * (block - last_block) + 1) -
1956 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1957 } else {
1958 if (p_i93->rw_offset == 0) {
1959 p_i93->max_ndef_length =
1960 p_i93->ndef_length
1961 /* add available bytes in the last block of NDEF TLV */
1962 + p_i93->block_size -
1963 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1964
1965 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1966 } else {
1967 first_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001968 }
1969
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001970 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1971 num_blocks = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001972
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001973 for (block = first_block; block < num_blocks; block++) {
1974 /* if any block of NDEF TLV is locked */
1975 if ((block + p_i93->rw_offset) <= last_block) {
1976 if (*(p + block) & I93_BLOCK_LOCKED) {
1977 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1978 break;
1979 }
1980 } else {
1981 if (*(p + block) & I93_BLOCK_LOCKED) {
1982 /* no more consecutive unlocked block */
1983 break;
1984 } else {
1985 /* add block size if not locked */
1986 p_i93->max_ndef_length += p_i93->block_size;
1987 }
1988 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001989 }
1990
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001991 /* update next security of block to check */
1992 p_i93->rw_offset += num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001993
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001994 /* if need to check more */
1995 if (p_i93->num_block > p_i93->rw_offset) {
1996 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
1997 rw_i93_handle_error(NFC_STATUS_FAILED);
1998 }
1999 break;
2000 }
2001 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002002
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002003 /* check if need to adjust max NDEF length */
2004 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
2005 /* 3 bytes length field must be used */
2006 p_i93->max_ndef_length -= 2;
2007 }
2008
2009 rw_data.ndef.status = NFC_STATUS_OK;
Love Khanna57a3dfa2017-03-28 20:03:38 +05302010 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002011 rw_data.ndef.flags = 0;
2012 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
2013 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
2014 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2015 rw_data.ndef.cur_size = p_i93->ndef_length;
2016
2017 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
2018 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
2019 rw_data.ndef.max_size = p_i93->ndef_length;
2020 } else {
2021 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
2022 rw_data.ndef.max_size = p_i93->max_ndef_length;
2023 }
2024
2025 p_i93->state = RW_I93_STATE_IDLE;
2026 p_i93->sent_cmd = 0;
2027
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002028 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2029 "NDEF cur_size(%d),max_size (%d), flags (0x%x)",
2030 rw_data.ndef.cur_size, rw_data.ndef.max_size, rw_data.ndef.flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002031
2032 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
2033 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002034
2035 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002036 break;
2037 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002038}
2039
2040/*******************************************************************************
2041**
2042** Function rw_i93_sm_read_ndef
2043**
2044** Description Process NDEF read procedure
2045**
2046** Returns void
2047**
2048*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002049void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
2050 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2051 uint8_t flags;
2052 uint16_t offset, length = p_resp->len;
2053 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2054 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002055
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002056 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002057
Jack Yu46defd32019-01-30 14:59:09 +08002058 if (length == 0) {
2059 android_errorWriteLog(0x534e4554, "122035770");
2060 rw_i93_handle_error(NFC_STATUS_FAILED);
2061 return;
2062 }
2063
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002064 STREAM_TO_UINT8(flags, p);
2065 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002066
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002067 if (flags & I93_FLAG_ERROR_DETECTED) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002068 DLOG_IF(INFO, nfc_debug_enabled)
2069 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002070 rw_i93_handle_error(NFC_STATUS_FAILED);
2071 return;
2072 }
2073
2074 /* if this is the first block */
2075 if (p_i93->rw_length == 0) {
2076 /* get start of NDEF in the first block */
2077 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
2078
2079 if (p_i93->ndef_length < 0xFF) {
2080 offset += 2;
2081 } else {
2082 offset += 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002083 }
2084
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002085 /* adjust offset if read more blocks because the first block doesn't have
2086 * NDEF */
2087 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
2088 } else {
2089 offset = 0;
2090 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002091
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002092 /* if read enough data to skip type and length field for the beginning */
2093 if (offset < length) {
2094 offset++; /* flags */
2095 p_resp->offset += offset;
2096 p_resp->len -= offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002097
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002098 rw_data.data.status = NFC_STATUS_OK;
2099 rw_data.data.p_data = p_resp;
2100
2101 p_i93->rw_length += p_resp->len;
2102 } else {
2103 /* in case of no Ndef data included */
2104 p_resp->len = 0;
2105 }
2106
2107 /* if read all of NDEF data */
2108 if (p_i93->rw_length >= p_i93->ndef_length) {
2109 /* remove extra btyes in the last block */
2110 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2111
2112 p_i93->state = RW_I93_STATE_IDLE;
2113 p_i93->sent_cmd = 0;
2114
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002115 DLOG_IF(INFO, nfc_debug_enabled)
2116 << StringPrintf("NDEF read complete read (%d)/total (%d)", p_resp->len,
2117 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002118
2119 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2120 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002121 DLOG_IF(INFO, nfc_debug_enabled)
2122 << StringPrintf("NDEF read segment read (%d)/total (%d)", p_resp->len,
2123 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002124
2125 if (p_resp->len > 0) {
2126 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002127 }
2128
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002129 /* this will make read data from next block */
2130 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002131
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002132 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2133 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002134 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002135 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002136}
2137
2138/*******************************************************************************
2139**
2140** Function rw_i93_sm_update_ndef
2141**
2142** Description Process NDEF update procedure
2143**
2144** 1. Set length field to zero
2145** 2. Write NDEF and Terminator TLV
2146** 3. Set length field to NDEF length
2147**
2148** Returns void
2149**
2150*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002151void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
2152 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2153 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2154 uint16_t length = p_resp->len, block_number;
2155 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2156 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002157
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002158 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2159 "sub_state:%s (0x%x)",
2160 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 -08002161
Jack Yu9b406b62019-01-30 15:10:07 +08002162 if (length == 0 || p_i93->block_size > I93_MAX_BLOCK_LENGH) {
2163 android_errorWriteLog(0x534e4554, "122320256");
2164 rw_i93_handle_error(NFC_STATUS_FAILED);
2165 return;
2166 }
2167
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002168 STREAM_TO_UINT8(flags, p);
2169 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002170
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002171 if (flags & I93_FLAG_ERROR_DETECTED) {
2172 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2173 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2174 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2175 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2176 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2177 /* ignore error */
2178 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002179 DLOG_IF(INFO, nfc_debug_enabled)
2180 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002181 rw_i93_handle_error(NFC_STATUS_FAILED);
2182 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002183 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002184 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002185
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002186 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002187 case RW_I93_SUBSTATE_RESET_LEN:
2188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002189 /* get offset of length field */
2190 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002191
Jack Yu9b406b62019-01-30 15:10:07 +08002192 if (length < length_offset) {
2193 android_errorWriteLog(0x534e4554, "122320256");
2194 rw_i93_handle_error(NFC_STATUS_FAILED);
2195 return;
2196 }
2197
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002198 /* set length to zero */
2199 *(p + length_offset) = 0x00;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002201 if (p_i93->ndef_length > 0) {
2202 /* if 3 bytes length field is needed */
2203 if (p_i93->ndef_length >= 0xFF) {
2204 xx = length_offset + 3;
2205 } else {
2206 xx = length_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002207 }
2208
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002209 /* write the first part of NDEF in the same block */
2210 for (; xx < p_i93->block_size; xx++) {
Jack Yu9b406b62019-01-30 15:10:07 +08002211 if (xx > length || p_i93->rw_length > p_i93->ndef_length) {
2212 android_errorWriteLog(0x534e4554, "122320256");
2213 rw_i93_handle_error(NFC_STATUS_FAILED);
2214 return;
2215 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002216 if (p_i93->rw_length < p_i93->ndef_length) {
2217 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2218 } else {
2219 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2220 }
2221 }
2222 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002224 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2225
George Chang82fd8252020-01-03 20:46:24 +08002226 if (length < p_i93->block_size) {
2227 android_errorWriteLog(0x534e4554, "143109193");
2228 rw_i93_handle_error(NFC_STATUS_FAILED);
2229 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2230 NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002231 /* update next writing offset */
2232 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2233 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2234 } else {
2235 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_WRITE_NDEF:
2240
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002241 /* if it's not the end of tag memory */
2242 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
2243 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002244
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002245 /* if we have more data to write */
2246 if (p_i93->rw_length < p_i93->ndef_length) {
2247 p = p_i93->p_update_data + p_i93->rw_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002248
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002249 p_i93->rw_offset += p_i93->block_size;
2250 p_i93->rw_length += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002251
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002252 /* if this is the last block of NDEF TLV */
2253 if (p_i93->rw_length > p_i93->ndef_length) {
2254 /* length of NDEF TLV in the block */
2255 xx = (uint8_t)(p_i93->block_size -
2256 (p_i93->rw_length - p_i93->ndef_length));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002257
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002258 /* set NULL TLV in the unused part of block */
2259 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2260 memcpy(buff, p, xx);
2261 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002262
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002263 /* if it's the end of tag memory */
2264 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2265 (xx < p_i93->block_size)) {
2266 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002267 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002268
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002269 p_i93->ndef_tlv_last_offset =
2270 p_i93->rw_offset - p_i93->block_size + xx - 1;
2271 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002272
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002273 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2274 NFC_STATUS_OK) {
2275 rw_i93_handle_error(NFC_STATUS_FAILED);
2276 }
2277 } else {
2278 /* if this is the very next block of NDEF TLV */
2279 if (block_number ==
2280 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2281 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002282
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002283 /* write Terminator TLV and NULL TLV */
2284 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2285 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2286 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002287
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002288 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2289 NFC_STATUS_OK) {
2290 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002291 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002292 } else {
2293 /* finished writing NDEF and Terminator TLV */
2294 /* read length field to update length */
2295 block_number =
2296 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2297
2298 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2299 NFC_STATUS_OK) {
2300 /* set offset to length field */
2301 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2302
2303 /* get size of length field */
2304 if (p_i93->ndef_length >= 0xFF) {
2305 p_i93->rw_length = 3;
2306 } else if (p_i93->ndef_length > 0) {
2307 p_i93->rw_length = 1;
2308 } else {
2309 p_i93->rw_length = 0;
2310 }
2311
2312 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2313 } else {
2314 rw_i93_handle_error(NFC_STATUS_FAILED);
2315 }
2316 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002317 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002318 } else {
2319 /* if we have no more data to write */
2320 if (p_i93->rw_length >= p_i93->ndef_length) {
2321 /* finished writing NDEF and Terminator TLV */
2322 /* read length field to update length */
2323 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002324
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002325 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2326 NFC_STATUS_OK) {
2327 /* set offset to length field */
2328 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002329
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002330 /* get size of length field */
2331 if (p_i93->ndef_length >= 0xFF) {
2332 p_i93->rw_length = 3;
2333 } else if (p_i93->ndef_length > 0) {
2334 p_i93->rw_length = 1;
2335 } else {
2336 p_i93->rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002337 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002338
2339 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2340 break;
2341 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002342 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002343 rw_i93_handle_error(NFC_STATUS_FAILED);
2344 }
2345 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002346
2347 case RW_I93_SUBSTATE_UPDATE_LEN:
2348
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002349 /* if we have more length field to write */
2350 if (p_i93->rw_length > 0) {
2351 /* if we got ack for writing, read next block to update rest of length
2352 * field */
2353 if (length == 0) {
2354 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002355
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002356 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2357 NFC_STATUS_OK) {
2358 rw_i93_handle_error(NFC_STATUS_FAILED);
2359 }
2360 } else {
2361 length_offset = p_i93->rw_offset % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002362
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002363 /* update length field within the read block */
2364 for (xx = length_offset; xx < p_i93->block_size; xx++) {
Jack Yu9b406b62019-01-30 15:10:07 +08002365 if (xx > length) {
2366 android_errorWriteLog(0x534e4554, "122320256");
2367 rw_i93_handle_error(NFC_STATUS_FAILED);
2368 return;
2369 }
2370
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002371 if (p_i93->rw_length == 3)
2372 *(p + xx) = 0xFF;
2373 else if (p_i93->rw_length == 2)
2374 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2375 else if (p_i93->rw_length == 1)
2376 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002377
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002378 p_i93->rw_length--;
2379 if (p_i93->rw_length == 0) break;
2380 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002381
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002382 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002383
George Chang82fd8252020-01-03 20:46:24 +08002384 if (length < p_i93->block_size) {
2385 android_errorWriteLog(0x534e4554, "143155861");
2386 rw_i93_handle_error(NFC_STATUS_FAILED);
2387 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2388 NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002389 /* set offset to the beginning of next block */
2390 p_i93->rw_offset +=
2391 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2392 } else {
2393 rw_i93_handle_error(NFC_STATUS_FAILED);
2394 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002395 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002396 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002397 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2398 "NDEF update complete, %d bytes, (%d-%d)", p_i93->ndef_length,
2399 p_i93->ndef_tlv_start_offset, p_i93->ndef_tlv_last_offset);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002400
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002401 p_i93->state = RW_I93_STATE_IDLE;
2402 p_i93->sent_cmd = 0;
2403 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002404
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002405 rw_data.status = NFC_STATUS_OK;
2406 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2407 }
2408 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002409
2410 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002411 break;
2412 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002413}
2414
2415/*******************************************************************************
2416**
2417** Function rw_i93_sm_format
2418**
2419** Description Process format procedure
2420**
2421** 1. Get UID
2422** 2. Get sys info for memory size (reset AFI/DSFID)
2423** 3. Get block status to get read-only status
2424** 4. Write CC and empty NDEF
2425**
2426** Returns void
2427**
2428*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002429void rw_i93_sm_format(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002430 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002431 uint8_t flags;
2432 uint16_t length = p_resp->len, xx, block_number;
2433 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2434 tRW_DATA rw_data;
2435 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002436
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002437 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2438 "sub_state:%s (0x%x)",
2439 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 -08002440
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002441 STREAM_TO_UINT8(flags, p);
2442 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002443
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002444 if (flags & I93_FLAG_ERROR_DETECTED) {
2445 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2446 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2447 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2448 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2449 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2450 /* ignore error */
2451 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2452 /* getting system info with protocol extension flag */
2453 /* This STM tag supports more than 2040 bytes */
2454 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2455 return;
2456 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002457 DLOG_IF(INFO, nfc_debug_enabled)
2458 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002459 rw_i93_handle_error(NFC_STATUS_FAILED);
2460 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002461 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002462 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002463
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002464 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002465 case RW_I93_SUBSTATE_WAIT_UID:
2466
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002467 p++; /* skip DSFID */
2468 p_uid = p_i93->uid;
2469 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002470
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002471 /* get system information to get memory size */
2472 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
2473 NFC_STATUS_OK) {
2474 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2475 } else {
2476 rw_i93_handle_error(NFC_STATUS_FAILED);
2477 }
2478 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002479
2480 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002482 p_i93->block_size = 0;
2483 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002484
Ruchi Kandoiba95bb12019-01-24 14:45:55 -08002485 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002486 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002487 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002488 }
2489
2490 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2491 /* DSFID, if any DSFID then reset */
2492 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2493 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2494 }
2495 }
2496 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2497 /* AFI, reset to 0 */
2498 if (p_i93->afi != 0x00) {
2499 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2500 }
2501 }
2502
2503 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002504 DLOG_IF(INFO, nfc_debug_enabled)
2505 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002506 rw_i93_handle_error(status);
2507 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2508 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2509 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2510 } else {
2511 rw_i93_handle_error(NFC_STATUS_FAILED);
2512 }
2513 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2514 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2515 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2516 } else {
2517 rw_i93_handle_error(NFC_STATUS_FAILED);
2518 }
2519 } else {
2520 /* get lock status to see if read-only */
2521 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2522 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2523 /* these doesn't support GetMultiBlockSecurityStatus */
2524
2525 rw_cb.tcb.i93.rw_offset = 0;
2526
2527 /* read blocks with option flag to get block security status */
2528 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2529 NFC_STATUS_OK) {
2530 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2531 } else {
2532 rw_i93_handle_error(NFC_STATUS_FAILED);
2533 }
2534 } else {
2535 /* block offset for read-only check */
2536 p_i93->rw_offset = 0;
2537
2538 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2539 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2540 } else {
2541 rw_i93_handle_error(NFC_STATUS_FAILED);
2542 }
2543 }
2544 }
2545
2546 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002547
2548 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2549
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002550 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2551 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2552 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2553 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2554 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002555
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002556 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2557 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2558 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2559 } else {
2560 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002561 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002562 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2563 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2564 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2565 } else {
2566 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002567 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002568 } else {
2569 /* get lock status to see if read-only */
2570 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2571 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2572 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002574 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002575
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002576 /* read blocks with option flag to get block security status */
2577 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2578 NFC_STATUS_OK) {
2579 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2580 } else {
2581 rw_i93_handle_error(NFC_STATUS_FAILED);
2582 }
2583 } else {
2584 /* block offset for read-only check */
2585 p_i93->rw_offset = 0;
Evan Chu85b7e842013-01-18 11:02:50 -05002586
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002587 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2588 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2589 } else {
2590 rw_i93_handle_error(NFC_STATUS_FAILED);
2591 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002592 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002593 }
2594 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002595
2596 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2597
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002598 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2599 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2600 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2601 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2602 if ((*p) & I93_BLOCK_LOCKED) {
2603 rw_i93_handle_error(NFC_STATUS_FAILED);
2604 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002605 }
2606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002607 /* if we checked all of user blocks */
2608 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2609 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2610 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2611 /* read the block which has AFI */
2612 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2613 rw_i93_send_cmd_read_single_block(
2614 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002615 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002616 }
2617 } else if (p_i93->rw_offset ==
2618 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2619 /* no block is locked */
2620 } else {
2621 p_i93->rw_offset += p_i93->block_size;
2622 rw_i93_send_cmd_read_single_block(
2623 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2624 break;
2625 }
2626 } else {
2627 /* if any block is locked, we cannot format it */
2628 for (xx = 0; xx < length; xx++) {
2629 if (*(p + xx) & I93_BLOCK_LOCKED) {
2630 rw_i93_handle_error(NFC_STATUS_FAILED);
2631 break;
2632 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002633 }
2634
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002635 /* update block offset for read-only check */
2636 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002637
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002638 /* if need to get more lock status of blocks */
2639 if (p_i93->num_block > p_i93->rw_offset) {
2640 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2641 rw_i93_handle_error(NFC_STATUS_FAILED);
2642 }
2643 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002644 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002645 }
Evan Chu85b7e842013-01-18 11:02:50 -05002646
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002647 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
George Chang37854142019-10-05 10:59:26 +08002648 /* Block size could be either 4 or 8 or 16 or 32 bytes */
2649 /* Get buffer for the largest block size I93_MAX_BLOCK_LENGH */
2650 p_i93->p_update_data = (uint8_t*)GKI_getbuf(I93_MAX_BLOCK_LENGH);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002651
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002652 if (!p_i93->p_update_data) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002653 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002654 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002655 break;
Alisher Alikhodjaev27013fe2020-07-23 14:38:34 -07002656 } else {
2657 switch (p_i93->block_size) {
2658 case 4:
2659 case 8:
2660 break;
2661 case 16:
2662 case 32: /* initialize unpopulated buffer b/139738828 */
2663 memset(p_i93->p_update_data, I93_ICODE_TLV_TYPE_NULL,
2664 I93_MAX_BLOCK_LENGH);
2665 break;
2666 default:
2667 android_errorWriteLog(0x534e4554, "157650336");
2668 rw_i93_handle_error(NFC_STATUS_FAILED);
2669 return;
2670 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002671 }
2672
2673 p = p_i93->p_update_data;
2674
2675 /* Capability Container */
Raphael Collado867d5c32017-03-27 12:49:40 +02002676 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002677 *(p++) = 0x40; /* version 1.0, read/write */
2678
2679 /* if memory size is less than 2048 bytes */
2680 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2681 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2682 8); /* memory size */
2683 else
2684 *(p++) = 0xFF;
2685
2686 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2687 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2688 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2689 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2690 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2691 else
2692 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2693 supported */
2694 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2695 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2696 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2697 supported */
2698 } else if ((p_i93->product_version ==
2699 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2700 (p_i93->product_version ==
2701 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2702 *(p++) = 0;
2703 } else {
2704 /* STM except LRIS2K, Broadcom supports read multi block command */
2705
2706 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2707 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2708 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2709 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2710 *(p++) = 0x00;
2711 else
2712 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2713 }
2714
2715 /* zero length NDEF and Terminator TLV */
2716 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2717 *(p++) = 0x00;
2718 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2719 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2720
2721 /* start from block 0 */
2722 p_i93->rw_offset = 0;
2723
2724 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2725 NFC_STATUS_OK) {
2726 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2727 p_i93->rw_offset += p_i93->block_size;
2728 } else {
2729 rw_i93_handle_error(NFC_STATUS_FAILED);
2730 }
2731 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002732
2733 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2734
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002735 /* if we have more data to write */
2736 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2737 block_number = (p_i93->rw_offset / p_i93->block_size);
2738 p = p_i93->p_update_data + p_i93->rw_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002739
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002740 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2741 NFC_STATUS_OK) {
2742 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2743 p_i93->rw_offset += p_i93->block_size;
2744 } else {
2745 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002746 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002747 } else {
2748 GKI_freebuf(p_i93->p_update_data);
2749 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002750
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002751 p_i93->state = RW_I93_STATE_IDLE;
2752 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002753
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002754 rw_data.status = NFC_STATUS_OK;
2755 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2756 }
2757 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002758
2759 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002760 break;
2761 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002762}
2763
2764/*******************************************************************************
2765**
2766** Function rw_i93_sm_set_read_only
2767**
2768** Description Process read-only procedure
2769**
2770** 1. Update CC as read-only
2771** 2. Lock all block of NDEF TLV
2772** 3. Lock block of CC
2773**
2774** Returns void
2775**
2776*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002777void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2778 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2779 uint8_t flags, block_number;
2780 uint16_t length = p_resp->len;
2781 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2782 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002783
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002784 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2785 "sub_state:%s (0x%x)",
2786 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 -08002787
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002788 STREAM_TO_UINT8(flags, p);
2789 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002790
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002791 if (flags & I93_FLAG_ERROR_DETECTED) {
2792 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2793 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2794 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2795 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2796 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2797 /* ignore error */
2798 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002799 DLOG_IF(INFO, nfc_debug_enabled)
2800 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002801 rw_i93_handle_error(NFC_STATUS_FAILED);
2802 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002803 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002804 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002805
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002806 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002807 case RW_I93_SUBSTATE_WAIT_CC:
2808
George Changec0e2332019-08-16 20:37:23 +08002809 if (length < RW_I93_CC_SIZE) {
2810 android_errorWriteLog(0x534e4554, "139188579");
2811 rw_i93_handle_error(NFC_STATUS_FAILED);
2812 return;
2813 }
2814
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002815 /* mark CC as read-only */
2816 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002817
George Chang82fd8252020-01-03 20:46:24 +08002818 if (length < p_i93->block_size) {
2819 android_errorWriteLog(0x534e4554, "143106535");
2820 rw_i93_handle_error(NFC_STATUS_FAILED);
2821 } else if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002822 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2823 } else {
2824 rw_i93_handle_error(NFC_STATUS_FAILED);
2825 }
2826 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002827
2828 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2829
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002830 /* successfully write CC then lock all blocks of NDEF TLV */
2831 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2832 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002833
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002834 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2835 p_i93->rw_offset += p_i93->block_size;
2836 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2837 } else {
2838 rw_i93_handle_error(NFC_STATUS_FAILED);
2839 }
2840 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002841
2842 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2843
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002844 /* if we need to lock more blocks */
2845 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
2846 /* get the next block of NDEF TLV */
2847 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002848
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002849 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2850 p_i93->rw_offset += p_i93->block_size;
2851 } else {
2852 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002853 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002854 }
2855 /* if the first block of NDEF TLV is different from block of CC */
2856 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
2857 /* lock block of CC */
2858 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
2859 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2860 } else {
2861 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002862 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002863 } else {
2864 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2865 p_i93->state = RW_I93_STATE_IDLE;
2866 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002867
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002868 rw_data.status = NFC_STATUS_OK;
2869 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2870 }
2871 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002872
2873 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2874
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002875 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2876 p_i93->state = RW_I93_STATE_IDLE;
2877 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002878
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002879 rw_data.status = NFC_STATUS_OK;
2880 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2881 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002882
2883 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002884 break;
2885 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002886}
2887
2888/*******************************************************************************
2889**
2890** Function rw_i93_handle_error
2891**
2892** Description notify error to application and clean up
2893**
2894** Returns none
2895**
2896*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002897void rw_i93_handle_error(tNFC_STATUS status) {
2898 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2899 tRW_DATA rw_data;
2900 tRW_EVENT event;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002901
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002902 DLOG_IF(INFO, nfc_debug_enabled)
2903 << StringPrintf("status:0x%02X, state:0x%X", status, p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002904
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002905 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002906
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002907 if (rw_cb.p_cback) {
2908 rw_data.status = status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002909
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002910 switch (p_i93->state) {
2911 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2912 event = RW_I93_INTF_ERROR_EVT;
2913 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002914
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002915 case RW_I93_STATE_BUSY:
2916 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
2917 /* There is no response to Stay Quiet command */
2918 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2919 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2920 rw_data.i93_cmd_cmpl.error_code = 0;
2921 event = RW_I93_CMD_CMPL_EVT;
2922 } else {
2923 event = RW_I93_INTF_ERROR_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002924 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002925 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002926
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002927 case RW_I93_STATE_DETECT_NDEF:
Love Khanna57a3dfa2017-03-28 20:03:38 +05302928 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002929 rw_data.ndef.cur_size = 0;
2930 rw_data.ndef.max_size = 0;
2931 rw_data.ndef.flags = 0;
2932 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2933 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2934 event = RW_I93_NDEF_DETECT_EVT;
2935 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002936
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002937 case RW_I93_STATE_READ_NDEF:
2938 event = RW_I93_NDEF_READ_FAIL_EVT;
2939 break;
2940
2941 case RW_I93_STATE_UPDATE_NDEF:
2942 p_i93->p_update_data = NULL;
2943 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2944 break;
2945
2946 case RW_I93_STATE_FORMAT:
2947 if (p_i93->p_update_data) {
2948 GKI_freebuf(p_i93->p_update_data);
2949 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002950 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002951 event = RW_I93_FORMAT_CPLT_EVT;
2952 break;
2953
2954 case RW_I93_STATE_SET_READ_ONLY:
2955 event = RW_I93_SET_TAG_RO_EVT;
2956 break;
2957
2958 case RW_I93_STATE_PRESENCE_CHECK:
2959 event = RW_I93_PRESENCE_CHECK_EVT;
2960 break;
2961
2962 default:
2963 event = RW_I93_MAX_EVT;
2964 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002965 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002966
2967 p_i93->state = RW_I93_STATE_IDLE;
2968 p_i93->sent_cmd = 0;
2969
2970 if (event != RW_I93_MAX_EVT) {
2971 (*(rw_cb.p_cback))(event, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002972 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002973 } else {
2974 p_i93->state = RW_I93_STATE_IDLE;
2975 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002976}
2977
2978/*******************************************************************************
2979**
2980** Function rw_i93_process_timeout
2981**
2982** Description process timeout event
2983**
2984** Returns none
2985**
2986*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002987void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2988 NFC_HDR* p_buf;
Evan Chu85b7e842013-01-18 11:02:50 -05002989
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002990 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002991
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002992 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
2993 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
2994 (rw_cb.tcb.i93.p_retry_cmd) &&
2995 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
2996 rw_cb.tcb.i93.retry_count++;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002997 LOG(ERROR) << StringPrintf("retry_count = %d", rw_cb.tcb.i93.retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05002998
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002999 p_buf = rw_cb.tcb.i93.p_retry_cmd;
3000 rw_cb.tcb.i93.p_retry_cmd = NULL;
Evan Chu7c69b272013-05-14 12:48:36 -04003001
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003002 if (rw_i93_send_to_lower(p_buf)) {
3003 return;
3004 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003005 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003006
3007 /* all retrial is done or failed to send command to lower layer */
3008 if (rw_cb.tcb.i93.p_retry_cmd) {
3009 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
3010 rw_cb.tcb.i93.p_retry_cmd = NULL;
3011 rw_cb.tcb.i93.retry_count = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003012 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003013 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
3014 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003015 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003016 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003017}
3018
3019/*******************************************************************************
3020**
3021** Function rw_i93_data_cback
3022**
3023** Description This callback function receives the data from NFCC.
3024**
3025** Returns none
3026**
3027*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07003028static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
3029 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003030 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3031 NFC_HDR* p_resp;
3032 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003033
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003034 uint8_t begin_state = p_i93->state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003035
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003036 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003037
Love Khanna57a3dfa2017-03-28 20:03:38 +05303038 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
3039 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003040 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003041
Jizhou Liao499be102017-08-11 12:57:12 -07003042 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003043 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
3044 p_i93->retry_count++;
Evan Chu85b7e842013-01-18 11:02:50 -05003045
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003046 LOG(ERROR) << StringPrintf("retry_count = %d", p_i93->retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05003047
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003048 p_resp = p_i93->p_retry_cmd;
3049 p_i93->p_retry_cmd = NULL;
3050 if (rw_i93_send_to_lower(p_resp)) {
3051 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003052 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003053 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003054
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003055 /* all retrial is done or failed to send command to lower layer */
3056 if (p_i93->p_retry_cmd) {
3057 GKI_freebuf(p_i93->p_retry_cmd);
Evan Chu85b7e842013-01-18 11:02:50 -05003058 p_i93->p_retry_cmd = NULL;
3059 p_i93->retry_count = 0;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003060 }
3061
3062 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
3063 } else {
3064 /* free retry buffer */
3065 if (p_i93->p_retry_cmd) {
3066 GKI_freebuf(p_i93->p_retry_cmd);
3067 p_i93->p_retry_cmd = NULL;
3068 p_i93->retry_count = 0;
3069 }
3070 NFC_SetStaticRfCback(NULL);
3071 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
Evan Chu85b7e842013-01-18 11:02:50 -05003072 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003073 return;
3074 }
3075
3076 if (event != NFC_DATA_CEVT) {
3077 return;
3078 }
3079
3080 p_resp = (NFC_HDR*)p_data->data.p_data;
3081
3082 nfc_stop_quick_timer(&p_i93->timer);
3083
3084 /* free retry buffer */
3085 if (p_i93->p_retry_cmd) {
3086 GKI_freebuf(p_i93->p_retry_cmd);
3087 p_i93->p_retry_cmd = NULL;
3088 p_i93->retry_count = 0;
3089 }
Evan Chu85b7e842013-01-18 11:02:50 -05003090
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003091 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
3092 "RW I93 state: <%s (%d)>", rw_i93_get_state_name(p_i93->state).c_str(),
3093 p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003094
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003095 switch (p_i93->state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003096 case RW_I93_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003097 /* Unexpected Response from VICC, it should be raw frame response */
3098 /* forward to upper layer without parsing */
3099 p_i93->sent_cmd = 0;
3100 if (rw_cb.p_cback) {
3101 rw_data.raw_frame.status = p_data->data.status;
3102 rw_data.raw_frame.p_data = p_resp;
3103 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
3104 p_resp = NULL;
3105 } else {
3106 GKI_freebuf(p_resp);
3107 }
3108 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003109 case RW_I93_STATE_BUSY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003110 p_i93->state = RW_I93_STATE_IDLE;
3111 rw_i93_send_to_upper(p_resp);
3112 GKI_freebuf(p_resp);
3113 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003114
3115 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003116 rw_i93_sm_detect_ndef(p_resp);
3117 GKI_freebuf(p_resp);
3118 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003119
3120 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003121 rw_i93_sm_read_ndef(p_resp);
3122 /* p_resp may send upper lyaer */
3123 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003124
3125 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003126 rw_i93_sm_update_ndef(p_resp);
3127 GKI_freebuf(p_resp);
3128 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003129
3130 case RW_I93_STATE_FORMAT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003131 rw_i93_sm_format(p_resp);
3132 GKI_freebuf(p_resp);
3133 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003134
3135 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003136 rw_i93_sm_set_read_only(p_resp);
3137 GKI_freebuf(p_resp);
3138 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003139
3140 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003141 p_i93->state = RW_I93_STATE_IDLE;
3142 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003143
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003144 /* if any response, send presence check with ok */
3145 rw_data.status = NFC_STATUS_OK;
3146 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3147 GKI_freebuf(p_resp);
3148 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003149
3150 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003151 LOG(ERROR) << StringPrintf("invalid state=%d", p_i93->state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003152 GKI_freebuf(p_resp);
3153 break;
3154 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003155
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003156 if (begin_state != p_i93->state) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003157 DLOG_IF(INFO, nfc_debug_enabled)
3158 << StringPrintf("RW I93 state changed:<%s> -> <%s>",
3159 rw_i93_get_state_name(begin_state).c_str(),
3160 rw_i93_get_state_name(p_i93->state).c_str());
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003161 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003162}
3163
3164/*******************************************************************************
3165**
3166** Function rw_i93_select
3167**
Love Khanna57a3dfa2017-03-28 20:03:38 +05303168** Description Initialise ISO 15693 / T5T RW
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003169**
3170** Returns NFC_STATUS_OK if success
3171**
3172*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003173tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
3174 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3175 uint8_t uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003176
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003177 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003179 NFC_SetStaticRfCback(rw_i93_data_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003180
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003181 p_i93->state = RW_I93_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003182
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003183 /* convert UID to big endian format - MSB(0xE0) in first byte */
3184 p = uid;
3185 STREAM_TO_ARRAY8(p, p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003186
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003187 rw_i93_get_product_version(uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003188
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003189 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003190}
3191
3192/*******************************************************************************
3193**
3194** Function RW_I93Inventory
3195**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003196** Description This function send Inventory command with/without AFI
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003197** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3198**
3199** RW_I93_RESPONSE_EVT will be returned
3200**
3201** Returns NFC_STATUS_OK if success
3202** NFC_STATUS_NO_BUFFERS if out of buffer
3203** NFC_STATUS_BUSY if busy
3204** NFC_STATUS_FAILED if other error
3205**
3206*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003207tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3208 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003209
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003210 DLOG_IF(INFO, nfc_debug_enabled)
3211 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003212
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003213 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003214 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3215 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003216 return NFC_STATUS_BUSY;
3217 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003218
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003219 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003220
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003221 if (status == NFC_STATUS_OK) {
3222 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3223 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003224
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003225 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003226}
3227
3228/*******************************************************************************
3229**
3230** Function RW_I93StayQuiet
3231**
3232** Description This function send Inventory command
3233**
3234** RW_I93_CMD_CMPL_EVT will be returned
3235**
3236** Returns NFC_STATUS_OK if success
3237** NFC_STATUS_NO_BUFFERS if out of buffer
3238** NFC_STATUS_BUSY if busy
3239** NFC_STATUS_FAILED if other error
3240**
3241*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003242tNFC_STATUS RW_I93StayQuiet(void) {
3243 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003244
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003245 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003246
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003247 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003248 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3249 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003250 return NFC_STATUS_BUSY;
3251 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003252
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003253 status = rw_i93_send_cmd_stay_quiet();
3254 if (status == NFC_STATUS_OK) {
3255 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3256 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003257
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003258 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003259}
3260
3261/*******************************************************************************
3262**
3263** Function RW_I93ReadSingleBlock
3264**
3265** Description This function send Read Single Block command
3266**
3267** RW_I93_RESPONSE_EVT will be returned
3268**
3269** Returns NFC_STATUS_OK if success
3270** NFC_STATUS_NO_BUFFERS if out of buffer
3271** NFC_STATUS_BUSY if busy
3272** NFC_STATUS_FAILED if other error
3273**
3274*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003275tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3276 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003277
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003278 DLOG_IF(INFO, nfc_debug_enabled)
3279 << StringPrintf("block_number:0x%02X", block_number);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003280
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003281 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003282 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3283 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003284 return NFC_STATUS_BUSY;
3285 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003286
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003287 status = rw_i93_send_cmd_read_single_block(block_number, false);
3288 if (status == NFC_STATUS_OK) {
3289 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3290 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003291
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003292 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003293}
3294
3295/*******************************************************************************
3296**
3297** Function RW_I93WriteSingleBlock
3298**
3299** Description This function send Write Single Block command
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003300** Application must get block size first by calling
3301** RW_I93GetSysInfo().
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003302**
3303** RW_I93_CMD_CMPL_EVT will be returned
3304**
3305** Returns NFC_STATUS_OK if success
3306** NFC_STATUS_NO_BUFFERS if out of buffer
3307** NFC_STATUS_BUSY if busy
3308** NFC_STATUS_FAILED if other error
3309**
3310*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003311tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3312 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003313
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003314 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003315
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003316 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003317 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3318 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003319 return NFC_STATUS_BUSY;
3320 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003321
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003322 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003323 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003324 return NFC_STATUS_FAILED;
3325 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003326
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003327 status = rw_i93_send_cmd_write_single_block(block_number, p_data);
3328 if (status == NFC_STATUS_OK) {
3329 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3330 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003331
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003332 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003333}
3334
3335/*******************************************************************************
3336**
3337** Function RW_I93LockBlock
3338**
3339** Description This function send Lock Block command
3340**
3341** RW_I93_CMD_CMPL_EVT will be returned
3342**
3343** Returns NFC_STATUS_OK if success
3344** NFC_STATUS_NO_BUFFERS if out of buffer
3345** NFC_STATUS_BUSY if busy
3346** NFC_STATUS_FAILED if other error
3347**
3348*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003349tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3350 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003351
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003352 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003353
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003354 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003355 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3356 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003357 return NFC_STATUS_BUSY;
3358 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003359
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003360 status = rw_i93_send_cmd_lock_block(block_number);
3361 if (status == NFC_STATUS_OK) {
3362 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3363 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003364
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003365 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003366}
3367
3368/*******************************************************************************
3369**
3370** Function RW_I93ReadMultipleBlocks
3371**
3372** Description This function send Read Multiple Blocks command
3373**
3374** RW_I93_RESPONSE_EVT will be returned
3375**
3376** Returns NFC_STATUS_OK if success
3377** NFC_STATUS_NO_BUFFERS if out of buffer
3378** NFC_STATUS_BUSY if busy
3379** NFC_STATUS_FAILED if other error
3380**
3381*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003382tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3383 uint16_t number_blocks) {
3384 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003385
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003386 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003387
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003388 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003389 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3390 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003391 return NFC_STATUS_BUSY;
3392 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003393
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003394 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3395 if (status == NFC_STATUS_OK) {
3396 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3397 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003398
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003399 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003400}
3401
3402/*******************************************************************************
3403**
3404** Function RW_I93WriteMultipleBlocks
3405**
3406** Description This function send Write Multiple Blocks command
3407**
3408** RW_I93_CMD_CMPL_EVT will be returned
3409**
3410** Returns NFC_STATUS_OK if success
3411** NFC_STATUS_NO_BUFFERS if out of buffer
3412** NFC_STATUS_BUSY if busy
3413** NFC_STATUS_FAILED if other error
3414**
3415*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02003416tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003417 uint16_t number_blocks, uint8_t* p_data) {
3418 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003419
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003420 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003421
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003422 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003423 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3424 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003425 return NFC_STATUS_BUSY;
3426 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003427
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003428 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003429 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003430 return NFC_STATUS_FAILED;
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_write_multi_blocks(first_block_number, number_blocks,
3434 p_data);
3435 if (status == NFC_STATUS_OK) {
3436 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3437 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003438
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003439 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003440}
3441
3442/*******************************************************************************
3443**
3444** Function RW_I93Select
3445**
3446** Description This function send Select command
3447**
3448** UID[0]: 0xE0, MSB
3449** UID[1]: IC Mfg Code
3450** ...
3451** UID[7]: LSB
3452**
3453** RW_I93_CMD_CMPL_EVT will be returned
3454**
3455** Returns NFC_STATUS_OK if success
3456** NFC_STATUS_NO_BUFFERS if out of buffer
3457** NFC_STATUS_BUSY if busy
3458** NFC_STATUS_FAILED if other error
3459**
3460*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003461tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3462 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003463
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003464 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003465
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003466 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003467 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3468 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003469 return NFC_STATUS_BUSY;
3470 }
3471
3472 if (p_uid) {
3473 status = rw_i93_send_cmd_select(p_uid);
3474 if (status == NFC_STATUS_OK) {
3475 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003476 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003477 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003478 LOG(ERROR) << StringPrintf("UID shall be provided");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003479 status = NFC_STATUS_FAILED;
3480 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003481
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003482 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003483}
3484
3485/*******************************************************************************
3486**
3487** Function RW_I93ResetToReady
3488**
3489** Description This function send Reset To Ready command
3490**
3491** RW_I93_CMD_CMPL_EVT will be returned
3492**
3493** Returns NFC_STATUS_OK if success
3494** NFC_STATUS_NO_BUFFERS if out of buffer
3495** NFC_STATUS_BUSY if busy
3496** NFC_STATUS_FAILED if other error
3497**
3498*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003499tNFC_STATUS RW_I93ResetToReady(void) {
3500 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003501
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003502 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003503
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003504 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003505 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3506 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003507 return NFC_STATUS_BUSY;
3508 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003509
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003510 status = rw_i93_send_cmd_reset_to_ready();
3511 if (status == NFC_STATUS_OK) {
3512 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3513 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003514
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003515 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003516}
3517
3518/*******************************************************************************
3519**
3520** Function RW_I93WriteAFI
3521**
3522** Description This function send Write AFI command
3523**
3524** RW_I93_CMD_CMPL_EVT will be returned
3525**
3526** Returns NFC_STATUS_OK if success
3527** NFC_STATUS_NO_BUFFERS if out of buffer
3528** NFC_STATUS_BUSY if busy
3529** NFC_STATUS_FAILED if other error
3530**
3531*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003532tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3533 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003534
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003535 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003536
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003537 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003538 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3539 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003540 return NFC_STATUS_BUSY;
3541 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003542
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003543 status = rw_i93_send_cmd_write_afi(afi);
3544 if (status == NFC_STATUS_OK) {
3545 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3546 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003547
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003548 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003549}
3550
3551/*******************************************************************************
3552**
3553** Function RW_I93LockAFI
3554**
3555** Description This function send Lock AFI command
3556**
3557** RW_I93_CMD_CMPL_EVT will be returned
3558**
3559** Returns NFC_STATUS_OK if success
3560** NFC_STATUS_NO_BUFFERS if out of buffer
3561** NFC_STATUS_BUSY if busy
3562** NFC_STATUS_FAILED if other error
3563**
3564*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003565tNFC_STATUS RW_I93LockAFI(void) {
3566 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003567
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003568 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003569
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003570 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003571 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3572 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003573 return NFC_STATUS_BUSY;
3574 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003575
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003576 status = rw_i93_send_cmd_lock_afi();
3577 if (status == NFC_STATUS_OK) {
3578 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3579 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003580
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003581 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003582}
3583
3584/*******************************************************************************
3585**
3586** Function RW_I93WriteDSFID
3587**
3588** Description This function send Write DSFID command
3589**
3590** RW_I93_CMD_CMPL_EVT will be returned
3591**
3592** Returns NFC_STATUS_OK if success
3593** NFC_STATUS_NO_BUFFERS if out of buffer
3594** NFC_STATUS_BUSY if busy
3595** NFC_STATUS_FAILED if other error
3596**
3597*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003598tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3599 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003600
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003601 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003602
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003603 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003604 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3605 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003606 return NFC_STATUS_BUSY;
3607 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003608
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003609 status = rw_i93_send_cmd_write_dsfid(dsfid);
3610 if (status == NFC_STATUS_OK) {
3611 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3612 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003613
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003614 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003615}
3616
3617/*******************************************************************************
3618**
3619** Function RW_I93LockDSFID
3620**
3621** Description This function send Lock DSFID command
3622**
3623** RW_I93_CMD_CMPL_EVT will be returned
3624**
3625** Returns NFC_STATUS_OK if success
3626** NFC_STATUS_NO_BUFFERS if out of buffer
3627** NFC_STATUS_BUSY if busy
3628** NFC_STATUS_FAILED if other error
3629**
3630*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003631tNFC_STATUS RW_I93LockDSFID(void) {
3632 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003633
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003634 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003635
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003636 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003637 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3638 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003639 return NFC_STATUS_BUSY;
3640 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003641
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003642 status = rw_i93_send_cmd_lock_dsfid();
3643 if (status == NFC_STATUS_OK) {
3644 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3645 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003646
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003647 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003648}
3649
3650/*******************************************************************************
3651**
3652** Function RW_I93GetSysInfo
3653**
3654** Description This function send Get System Information command
3655**
3656** RW_I93_RESPONSE_EVT will be returned
3657**
3658** Returns NFC_STATUS_OK if success
3659** NFC_STATUS_NO_BUFFERS if out of buffer
3660** NFC_STATUS_BUSY if busy
3661** NFC_STATUS_FAILED if other error
3662**
3663*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003664tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3665 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003666
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003667 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003668
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003669 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003670 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3671 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003672 return NFC_STATUS_BUSY;
3673 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003674
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003675 if (p_uid) {
3676 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3677 } else {
3678 status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
3679 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003680
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003681 if (status == NFC_STATUS_OK) {
3682 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3683 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003684
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003685 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003686}
3687
3688/*******************************************************************************
3689**
3690** Function RW_I93GetMultiBlockSecurityStatus
3691**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003692** Description This function send Get Multiple Block Security Status
3693** command
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003694**
3695** RW_I93_RESPONSE_EVT will be returned
3696**
3697** Returns NFC_STATUS_OK if success
3698** NFC_STATUS_NO_BUFFERS if out of buffer
3699** NFC_STATUS_BUSY if busy
3700** NFC_STATUS_FAILED if other error
3701**
3702*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003703tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3704 uint16_t number_blocks) {
3705 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003706
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003707 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003708
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003709 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003710 LOG(ERROR) << StringPrintf(
3711 "Unable to start command at state "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003712 "(0x%X)",
3713 rw_cb.tcb.i93.state);
3714 return NFC_STATUS_BUSY;
3715 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003716
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003717 status =
3718 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3719 if (status == NFC_STATUS_OK) {
3720 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3721 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003722
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003723 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003724}
3725
3726/*******************************************************************************
3727**
3728** Function RW_I93DetectNDef
3729**
3730** Description This function performs NDEF detection procedure
3731**
3732** RW_I93_NDEF_DETECT_EVT will be returned
3733**
3734** Returns NFC_STATUS_OK if success
3735** NFC_STATUS_FAILED if busy or other error
3736**
3737*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003738tNFC_STATUS RW_I93DetectNDef(void) {
3739 tNFC_STATUS status;
3740 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003741
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003742 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003743
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003744 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003745 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3746 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003747 return NFC_STATUS_FAILED;
3748 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003749
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003750 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
3751 status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
3752 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3753 } else if ((rw_cb.tcb.i93.num_block == 0) ||
3754 (rw_cb.tcb.i93.block_size == 0)) {
3755 status =
3756 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3757 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003758
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003759 /* clear all flags */
3760 rw_cb.tcb.i93.intl_flags = 0;
3761 } else {
3762 /* read CC in the first block */
3763 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3764 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3765 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003766
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003767 if (status == NFC_STATUS_OK) {
3768 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3769 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05003770
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003771 /* clear flags except flag for 2 bytes of number of blocks */
3772 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3773 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003775 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003776}
3777
3778/*******************************************************************************
3779**
3780** Function RW_I93ReadNDef
3781**
3782** Description This function performs NDEF read procedure
3783** Note: RW_I93DetectNDef () must be called before using this
3784**
3785** The following event will be returned
3786** RW_I93_NDEF_READ_EVT for each segmented NDEF message
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003787** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3788** complete NDEF
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003789** RW_I93_NDEF_READ_FAIL_EVT for failure
3790**
3791** Returns NFC_STATUS_OK if success
3792** NFC_STATUS_FAILED if I93 is busy or other error
3793**
3794*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003795tNFC_STATUS RW_I93ReadNDef(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003796 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003797
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003798 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003799 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3800 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003801 return NFC_STATUS_FAILED;
3802 }
3803
3804 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
3805 (rw_cb.tcb.i93.ndef_length > 0)) {
3806 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3807 rw_cb.tcb.i93.rw_length = 0;
3808
3809 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
3810 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3811 } else {
3812 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003813 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003814 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003815 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003816 return NFC_STATUS_FAILED;
3817 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003818
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003819 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003820}
3821
3822/*******************************************************************************
3823**
3824** Function RW_I93UpdateNDef
3825**
3826** Description This function performs NDEF update procedure
3827** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003828** Updating data must not be removed until returning
3829** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003830**
3831** The following event will be returned
3832** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3833** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3834**
3835** Returns NFC_STATUS_OK if success
3836** NFC_STATUS_FAILED if I93 is busy or other error
3837**
3838*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003839tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3840 uint16_t block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003841
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003842 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003843
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003844 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003845 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3846 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003847 return NFC_STATUS_FAILED;
3848 }
3849
3850 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3851 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003852 LOG(ERROR) << StringPrintf("NDEF is read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003853 return NFC_STATUS_FAILED;
3854 }
3855 if (rw_cb.tcb.i93.max_ndef_length < length) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003856 LOG(ERROR) << StringPrintf(
3857 "data (%d bytes) is more than max NDEF length "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003858 "(%d)",
3859 length, rw_cb.tcb.i93.max_ndef_length);
3860 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003861 }
3862
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003863 rw_cb.tcb.i93.ndef_length = length;
3864 rw_cb.tcb.i93.p_update_data = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003865
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003866 /* read length field */
3867 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3868 rw_cb.tcb.i93.rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003869
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003870 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003871
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003872 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
3873 NFC_STATUS_OK) {
3874 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3875 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3876 } else {
3877 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003878 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003879 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003880 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003881 return NFC_STATUS_FAILED;
3882 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003883
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003884 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003885}
3886
3887/*******************************************************************************
3888**
3889** Function RW_I93FormatNDef
3890**
3891** Description This function performs formatting procedure
3892**
3893** RW_I93_FORMAT_CPLT_EVT will be returned
3894**
3895** Returns NFC_STATUS_OK if success
3896** NFC_STATUS_FAILED if busy or other error
3897**
3898*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003899tNFC_STATUS RW_I93FormatNDef(void) {
3900 tNFC_STATUS status;
3901 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003902
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003903 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003904
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003905 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003906 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3907 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003908 return NFC_STATUS_FAILED;
3909 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003910
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003911 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
3912 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
3913 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
3914 */
3915 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003916
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003917 /* read blocks with option flag to get block security status */
3918 status = rw_i93_send_cmd_read_single_block(0x0000, true);
3919 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
3920 } else {
3921 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3922 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3923 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003924
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003925 if (status == NFC_STATUS_OK) {
3926 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
3927 rw_cb.tcb.i93.sub_state = sub_state;
3928 rw_cb.tcb.i93.intl_flags = 0;
3929 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003930
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003931 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003932}
3933
3934/*******************************************************************************
3935**
3936** Function RW_I93SetTagReadOnly
3937**
3938** Description This function performs NDEF read-only procedure
3939** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003940** Updating data must not be removed until returning
3941** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003942**
3943** The RW_I93_SET_TAG_RO_EVT event will be returned.
3944**
3945** Returns NFC_STATUS_OK if success
3946** NFC_STATUS_FAILED if I93 is busy or other error
3947**
3948*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003949tNFC_STATUS RW_I93SetTagReadOnly(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003950 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003952 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003953 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3954 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003955 return NFC_STATUS_FAILED;
3956 }
3957
3958 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3959 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003960 LOG(ERROR) << StringPrintf("NDEF is already read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003961 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003962 }
3963
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003964 /* get CC in the first block */
3965 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
3966 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
3967 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
3968 } else {
3969 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003970 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003971 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003972 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003973 return NFC_STATUS_FAILED;
3974 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003975
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003976 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003977}
3978
3979/*****************************************************************************
3980**
3981** Function RW_I93PresenceCheck
3982**
3983** Description Check if the tag is still in the field.
3984**
3985** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
3986** presence or non-presence.
3987**
3988** Returns NFC_STATUS_OK, if raw data frame sent
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003989** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3990** operation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003991** NFC_STATUS_FAILED: other error
3992**
3993*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003994tNFC_STATUS RW_I93PresenceCheck(void) {
3995 tNFC_STATUS status;
3996 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003997
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003998 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003999
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004000 if (!rw_cb.p_cback) {
4001 return NFC_STATUS_FAILED;
4002 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
4003 evt_data.status = NFC_STATUS_FAILED;
4004 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004005
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004006 return NFC_STATUS_OK;
4007 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
4008 return NFC_STATUS_BUSY;
4009 } else {
4010 /* The support of AFI by the VICC is optional, so do not include AFI */
4011 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
4012
4013 if (status == NFC_STATUS_OK) {
4014 /* do not retry during presence check */
4015 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
4016 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004017 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004018 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004019
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004020 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004021}
4022
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004023/*******************************************************************************
4024**
4025** Function rw_i93_get_state_name
4026**
4027** Description This function returns the state name.
4028**
4029** NOTE conditionally compiled to save memory.
4030**
4031** Returns pointer to the name
4032**
4033*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004034static std::string rw_i93_get_state_name(uint8_t state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004035 switch (state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004036 case RW_I93_STATE_NOT_ACTIVATED:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004037 return "NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004038 case RW_I93_STATE_IDLE:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004039 return "IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004040 case RW_I93_STATE_BUSY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004041 return "BUSY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004042 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004043 return "NDEF_DETECTION";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004044 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004045 return "READ_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004046 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004047 return "UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004048 case RW_I93_STATE_FORMAT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004049 return "FORMAT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004050 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004051 return "SET_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004052 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004053 return "PRESENCE_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004054 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004055 return "???? UNKNOWN STATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004056 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004057}
4058
4059/*******************************************************************************
4060**
4061** Function rw_i93_get_sub_state_name
4062**
4063** Description This function returns the sub_state name.
4064**
4065** NOTE conditionally compiled to save memory.
4066**
4067** Returns pointer to the name
4068**
4069*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004070static std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004071 switch (sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004072 case RW_I93_SUBSTATE_WAIT_UID:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004073 return "WAIT_UID";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004074 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004075 return "WAIT_SYS_INFO";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004076 case RW_I93_SUBSTATE_WAIT_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004077 return "WAIT_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004078 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004079 return "SEARCH_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004080 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004081 return "CHECK_LOCK_STATUS";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004082 case RW_I93_SUBSTATE_RESET_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004083 return "RESET_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004084 case RW_I93_SUBSTATE_WRITE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004085 return "WRITE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004086 case RW_I93_SUBSTATE_UPDATE_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004087 return "UPDATE_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004088 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004089 return "WAIT_RESET_DSFID_AFI";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004090 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004091 return "CHECK_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004092 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004093 return "WRITE_CC_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004094 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004095 return "WAIT_UPDATE_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004096 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004097 return "LOCK_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004098 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004099 return "WAIT_LOCK_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004100 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004101 return "???? UNKNOWN SUBSTATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004102 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004103}
Evan Chu85b7e842013-01-18 11:02:50 -05004104
4105/*******************************************************************************
4106**
4107** Function rw_i93_get_tag_name
4108**
4109** Description This function returns the tag name.
4110**
4111** NOTE conditionally compiled to save memory.
4112**
4113** Returns pointer to the name
4114**
4115*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004116static std::string rw_i93_get_tag_name(uint8_t product_version) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004117 switch (product_version) {
Evan Chu85b7e842013-01-18 11:02:50 -05004118 case RW_I93_ICODE_SLI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004119 return "SLI/SLIX";
Evan Chu85b7e842013-01-18 11:02:50 -05004120 case RW_I93_ICODE_SLI_S:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004121 return "SLI-S/SLIX-S";
Evan Chu85b7e842013-01-18 11:02:50 -05004122 case RW_I93_ICODE_SLI_L:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004123 return "SLI-L/SLIX-L";
Evan Chu85b7e842013-01-18 11:02:50 -05004124 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004125 return "Tag-it HF-I Plus Inlay";
Evan Chu85b7e842013-01-18 11:02:50 -05004126 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004127 return "Tag-it HF-I Plus Chip";
Evan Chu85b7e842013-01-18 11:02:50 -05004128 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004129 return "Tag-it HF-I Standard Chip/Inlyas";
Evan Chu85b7e842013-01-18 11:02:50 -05004130 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004131 return "Tag-it HF-I Pro Chip/Inlays";
Evan Chu85b7e842013-01-18 11:02:50 -05004132 case RW_I93_STM_LRI1K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004133 return "LRi1K";
Evan Chu85b7e842013-01-18 11:02:50 -05004134 case RW_I93_STM_LRI2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004135 return "LRi2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004136 case RW_I93_STM_LRIS2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004137 return "LRiS2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004138 case RW_I93_STM_LRIS64K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004139 return "LRiS64K";
Evan Chu85b7e842013-01-18 11:02:50 -05004140 case RW_I93_STM_M24LR64_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004141 return "M24LR64";
Evan Chu85b7e842013-01-18 11:02:50 -05004142 case RW_I93_STM_M24LR04E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004143 return "M24LR04E";
Evan Chu85b7e842013-01-18 11:02:50 -05004144 case RW_I93_STM_M24LR16E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004145 return "M24LR16E";
Evan Chu85b7e842013-01-18 11:02:50 -05004146 case RW_I93_STM_M24LR64E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004147 return "M24LR64E";
Raphael Collado867d5c32017-03-27 12:49:40 +02004148 case RW_I93_STM_ST25DV04K:
4149 return "ST25DV04";
4150 case RW_I93_STM_ST25DVHIK:
4151 return "ST25DV";
Evan Chu85b7e842013-01-18 11:02:50 -05004152 case RW_I93_UNKNOWN_PRODUCT:
4153 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004154 return "UNKNOWN";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004155 }
Evan Chu85b7e842013-01-18 11:02:50 -05004156}