blob: a8e095c356363a1dcc622f999401f4d3cd1beef6 [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
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080054
55/* main state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080056enum {
57 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
58 RW_I93_STATE_IDLE, /* waiting for upper layer API */
59 RW_I93_STATE_BUSY, /* waiting for response from tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080060
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080061 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
62 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
63 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
64 RW_I93_STATE_FORMAT, /* performing format procedure */
65 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080066
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080067 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080068};
69
70/* sub state */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080071enum {
72 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
73 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
74 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
75 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
76 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080077
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080078 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
79 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
80 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080081
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080082 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
83 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
84 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
85 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080086
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080087 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
88 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
89 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080090};
91
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -070092static std::string rw_i93_get_state_name(uint8_t state);
93static std::string rw_i93_get_sub_state_name(uint8_t sub_state);
94static std::string rw_i93_get_tag_name(uint8_t product_version);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080095
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -080096static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
97 tNFC_CONN* p_data);
98void rw_i93_handle_error(tNFC_STATUS status);
99tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
Raphael Collado867d5c32017-03-27 12:49:40 +0200100tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800101
102/*******************************************************************************
103**
104** Function rw_i93_get_product_version
105**
106** Description Get product version from UID
107**
108** Returns void
109**
110*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800111void rw_i93_get_product_version(uint8_t* p_uid) {
112 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800113
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800114 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
115 return;
116 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800117
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700118 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800119
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800120 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800121
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800122 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
123 if (p_uid[2] == I93_UID_ICODE_SLI)
124 p_i93->product_version = RW_I93_ICODE_SLI;
125 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
126 p_i93->product_version = RW_I93_ICODE_SLI_S;
127 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
128 p_i93->product_version = RW_I93_ICODE_SLI_L;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800129 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800130 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
131 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
132 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
133 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
134 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
135 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
136 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
137 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
138 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
139 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
140 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
141 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
142 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
143 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
144 else
145 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
146 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
147 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
148 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
149 p_i93->product_version = RW_I93_STM_M24LR04E_R;
150 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
151 p_i93->product_version = RW_I93_STM_M24LR16E_R;
152 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
153 p_i93->product_version = RW_I93_STM_M24LR64E_R;
Raphael Collado867d5c32017-03-27 12:49:40 +0200154 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DVHIK)
155 p_i93->product_version = RW_I93_STM_ST25DVHIK;
156 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DV04K)
157 p_i93->product_version = RW_I93_STM_ST25DV04K;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800158 else {
159 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
160 case I93_IC_REF_STM_LRI1K:
161 p_i93->product_version = RW_I93_STM_LRI1K;
162 break;
163 case I93_IC_REF_STM_LRI2K:
164 p_i93->product_version = RW_I93_STM_LRI2K;
165 break;
166 case I93_IC_REF_STM_LRIS2K:
167 p_i93->product_version = RW_I93_STM_LRIS2K;
168 break;
169 case I93_IC_REF_STM_LRIS64K:
170 p_i93->product_version = RW_I93_STM_LRIS64K;
171 break;
172 case I93_IC_REF_STM_M24LR64_R:
173 p_i93->product_version = RW_I93_STM_M24LR64_R;
174 break;
175 default:
176 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
177 break;
178 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800179 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800180 } else {
181 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
182 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800183
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700184 DLOG_IF(INFO, nfc_debug_enabled)
185 << StringPrintf("product_version = <%s>",
186 rw_i93_get_tag_name(p_i93->product_version).c_str());
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800187
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800188 switch (p_i93->product_version) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800189 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
190 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800191 /* these don't support Get System Information Command */
192 /* these support only Inventory, Stay Quiet, Read Single Block, Write
193 * Single Block, Lock Block */
194 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
195 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
196 break;
Evan Chu85b7e842013-01-18 11:02:50 -0500197 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800198 break;
199 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800200}
201
202/*******************************************************************************
203**
Raphael Collado867d5c32017-03-27 12:49:40 +0200204** Function rw_i93_process_ext_sys_info
205**
206** Description Store extended system information of tag
207**
208** Returns FALSE if retrying with protocol extension flag
209**
210*******************************************************************************/
Jack Yu8a86b1f2019-01-30 16:21:45 +0800211bool rw_i93_process_ext_sys_info(uint8_t* p_data, uint16_t length) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200212 uint8_t* p = p_data;
213 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
214 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
215
216 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
217
Jack Yu8a86b1f2019-01-30 16:21:45 +0800218 if (length < (I93_UID_BYTE_LEN + 1)) {
219 android_errorWriteLog(0x534e4554, "122316913");
220 return false;
221 }
222
Raphael Collado867d5c32017-03-27 12:49:40 +0200223 STREAM_TO_UINT8(p_i93->info_flags, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800224 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200225
226 p_uid = uid;
227 STREAM_TO_ARRAY8(p_uid, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800228 length -= I93_UID_BYTE_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200229
230 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800231 if (length < 1) {
232 android_errorWriteLog(0x534e4554, "122316913");
233 return false;
234 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200235 STREAM_TO_UINT8(p_i93->dsfid, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800236 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200237 }
238 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800239 if (length < 1) {
240 android_errorWriteLog(0x534e4554, "122316913");
241 return false;
242 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200243 STREAM_TO_UINT8(p_i93->afi, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800244 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200245 }
246 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800247 if (length < 3) {
248 android_errorWriteLog(0x534e4554, "122316913");
249 return false;
250 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200251 STREAM_TO_UINT16(p_i93->num_block, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800252 length -= I93_INFO_16BIT_NUM_BLOCK_LEN;
Raphael Collado867d5c32017-03-27 12:49:40 +0200253
254 /* it is one less than actual number of bytes */
255 p_i93->num_block += 1;
256
257 STREAM_TO_UINT8(p_i93->block_size, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800258 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200259 /* it is one less than actual number of blocks */
260 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
261 }
262 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Jack Yu8a86b1f2019-01-30 16:21:45 +0800263 if (length < 1) {
264 android_errorWriteLog(0x534e4554, "122316913");
265 return false;
266 }
Raphael Collado867d5c32017-03-27 12:49:40 +0200267 STREAM_TO_UINT8(p_i93->ic_reference, p);
Jack Yu8a86b1f2019-01-30 16:21:45 +0800268 length--;
Raphael Collado867d5c32017-03-27 12:49:40 +0200269
270 /* clear existing UID to set product version */
271 p_i93->uid[0] = 0x00;
272
273 /* store UID and get product version */
274 rw_i93_get_product_version(p_uid);
275
276 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
277 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
278 /* STM supports more than 2040 bytes */
279 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
280 }
281 }
282 }
283 return true;
284}
285
286/*******************************************************************************
287**
Evan Chu85b7e842013-01-18 11:02:50 -0500288** Function rw_i93_process_sys_info
289**
290** Description Store system information of tag
291**
292** Returns FALSE if retrying with protocol extension flag
293**
294*******************************************************************************/
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800295bool rw_i93_process_sys_info(uint8_t* p_data, uint16_t length) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800296 uint8_t* p = p_data;
297 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
298 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
Evan Chu85b7e842013-01-18 11:02:50 -0500299
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700300 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500301
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800302 if (length < (I93_UID_BYTE_LEN + 1)) {
303 android_errorWriteLog(0x534e4554, "121259048");
304 return false;
305 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800306 STREAM_TO_UINT8(p_i93->info_flags, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800307 length--;
Evan Chu85b7e842013-01-18 11:02:50 -0500308
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800309 p_uid = uid;
310 STREAM_TO_ARRAY8(p_uid, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800311 length -= I93_UID_BYTE_LEN;
Evan Chu85b7e842013-01-18 11:02:50 -0500312
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800313 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800314 if (length == 0) {
315 android_errorWriteLog(0x534e4554, "121259048");
316 return false;
317 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800318 STREAM_TO_UINT8(p_i93->dsfid, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800319 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800320 }
321 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800322 if (length == 0) {
323 android_errorWriteLog(0x534e4554, "121259048");
324 return false;
325 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800326 STREAM_TO_UINT8(p_i93->afi, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800327 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800328 }
329 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800330 bool block_16_bit = p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK;
331 if (block_16_bit && length > 2) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800332 STREAM_TO_UINT16(p_i93->num_block, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800333 length -= 2;
334 } else if (!block_16_bit && length > 1) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800335 STREAM_TO_UINT8(p_i93->num_block, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800336 length--;
337 } else {
338 android_errorWriteLog(0x534e4554, "121259048");
339 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500340 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800341 /* it is one less than actual number of bytes */
342 p_i93->num_block += 1;
Evan Chu85b7e842013-01-18 11:02:50 -0500343
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800344 STREAM_TO_UINT8(p_i93->block_size, p);
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800345 length--;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800346 /* it is one less than actual number of blocks */
347 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
348 }
349 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800350 if (length == 0) {
351 android_errorWriteLog(0x534e4554, "121259048");
352 return false;
353 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800354 STREAM_TO_UINT8(p_i93->ic_reference, p);
Evan Chu85b7e842013-01-18 11:02:50 -0500355
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800356 /* clear existing UID to set product version */
357 p_i93->uid[0] = 0x00;
Evan Chu85b7e842013-01-18 11:02:50 -0500358
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800359 /* store UID and get product version */
360 rw_i93_get_product_version(p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -0500361
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800362 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
363 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
364 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
365 p_i93->num_block = 8;
366 p_i93->block_size = 4;
367 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
368 /*
369 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
370 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
371 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
372 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
373 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
374 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
375 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
376 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
377 */
378 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
379 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
380 /*
381 ** M24LR16E-R or M24LR64E-R returns system information
382 ** without memory size, if option flag is not set.
383 ** LRIS64K and M24LR64-R return error if option flag is not
384 ** set.
385 */
386 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
387 /* get memory size with protocol extension flag */
388 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
389 NFC_STATUS_OK) {
390 /* STM supports more than 2040 bytes */
391 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
392
393 return false;
Evan Chu85b7e842013-01-18 11:02:50 -0500394 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800395 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800396 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
397 (p_i93->ic_reference == 0x21)) {
398 /* workaround of byte order in memory size information */
399 p_i93->num_block = 64;
400 p_i93->block_size = 4;
Raphael Collado867d5c32017-03-27 12:49:40 +0200401 } else if (!(p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)) {
402 if (!(p_i93->intl_flags & RW_I93_FLAG_EXT_COMMANDS)) {
403 if (rw_i93_send_cmd_get_ext_sys_info(NULL) == NFC_STATUS_OK) {
404 /* STM supports more than 2040 bytes */
405 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
406
407 return false;
408 }
409 }
Evan Chu85b7e842013-01-18 11:02:50 -0500410 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800411 }
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 return true;
Evan Chu85b7e842013-01-18 11:02:50 -0500416}
417
418/*******************************************************************************
419**
420** Function rw_i93_check_sys_info_prot_ext
421**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -0800422** Description Check if need to set protocol extension flag to get system
423** info
Evan Chu85b7e842013-01-18 11:02:50 -0500424**
425** Returns TRUE if sent Get System Info with protocol extension flag
426**
427*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800428bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
429 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
Evan Chu85b7e842013-01-18 11:02:50 -0500430
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700431 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -0500432
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800433 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
434 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
435 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
436 (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
437 NFC_STATUS_OK)) {
438 return true;
439 } else {
440 return false;
441 }
Evan Chu85b7e842013-01-18 11:02:50 -0500442}
443
444/*******************************************************************************
445**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800446** Function rw_i93_send_to_upper
447**
448** Description Send response to upper layer
449**
450** Returns void
451**
452*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800453void rw_i93_send_to_upper(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -0700454 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800455 uint16_t length = p_resp->len;
456 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
457 tRW_DATA rw_data;
458 uint8_t event = RW_I93_MAX_EVT;
459 uint8_t flags;
460 NFC_HDR* p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800461
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700462 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800463
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800464 STREAM_TO_UINT8(flags, p);
465 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800466
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800467 if (flags & I93_FLAG_ERROR_DETECTED) {
468 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
469 /* getting system info with protocol extension flag */
470 /* This STM tag supports more than 2040 bytes */
471 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
472 p_i93->state = RW_I93_STATE_BUSY;
473 } else {
474 /* notify error to upper layer */
475 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
476 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
477 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800478
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800479 rw_cb.tcb.i93.sent_cmd = 0;
480 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800481 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800482 return;
483 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800484
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800485 switch (p_i93->sent_cmd) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800486 case I93_CMD_INVENTORY:
487
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800488 /* forward inventory response */
489 rw_data.i93_inventory.status = NFC_STATUS_OK;
490 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800491
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800492 p_uid = rw_data.i93_inventory.uid;
493 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800494
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800495 /* store UID and get product version */
496 rw_i93_get_product_version(p_uid);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800497
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800498 event = RW_I93_INVENTORY_EVT;
499 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800500
501 case I93_CMD_READ_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200502 case I93_CMD_EXT_READ_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800503 case I93_CMD_READ_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200504 case I93_CMD_EXT_READ_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800505 case I93_CMD_GET_MULTI_BLK_SEC:
Raphael Collado867d5c32017-03-27 12:49:40 +0200506 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800507
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800508 /* forward tag data or security status */
509 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800510
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800511 if (p_buff) {
512 p_buff->offset = 0;
513 p_buff->len = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800514
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800515 memcpy((p_buff + 1), p, length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800516
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800517 rw_data.i93_data.status = NFC_STATUS_OK;
518 rw_data.i93_data.command = p_i93->sent_cmd;
519 rw_data.i93_data.p_data = p_buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800520
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800521 event = RW_I93_DATA_EVT;
522 } else {
523 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
524 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
525 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800526
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800527 event = RW_I93_CMD_CMPL_EVT;
528 }
529 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800530
531 case I93_CMD_WRITE_SINGLE_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200532 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800533 case I93_CMD_LOCK_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200534 case I93_CMD_EXT_LOCK_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800535 case I93_CMD_WRITE_MULTI_BLOCK:
Raphael Collado867d5c32017-03-27 12:49:40 +0200536 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800537 case I93_CMD_SELECT:
538 case I93_CMD_RESET_TO_READY:
539 case I93_CMD_WRITE_AFI:
540 case I93_CMD_LOCK_AFI:
541 case I93_CMD_WRITE_DSFID:
542 case I93_CMD_LOCK_DSFID:
543
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800544 /* notify the complete of command */
545 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
546 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
547 rw_data.i93_cmd_cmpl.error_code = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800548
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800549 event = RW_I93_CMD_CMPL_EVT;
550 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800551
552 case I93_CMD_GET_SYS_INFO:
553
Ruchi Kandoiba95bb12019-01-24 14:45:55 -0800554 if (rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800555 rw_data.i93_sys_info.status = NFC_STATUS_OK;
556 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
557 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
558 rw_data.i93_sys_info.afi = p_i93->afi;
559 rw_data.i93_sys_info.num_block = p_i93->num_block;
560 rw_data.i93_sys_info.block_size = p_i93->block_size;
561 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
Evan Chu85b7e842013-01-18 11:02:50 -0500562
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800563 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
Evan Chu85b7e842013-01-18 11:02:50 -0500564
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800565 event = RW_I93_SYS_INFO_EVT;
566 } else {
567 /* retrying with protocol extension flag */
568 p_i93->state = RW_I93_STATE_BUSY;
569 return;
570 }
571 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800572
Raphael Collado867d5c32017-03-27 12:49:40 +0200573 case I93_CMD_EXT_GET_SYS_INFO:
574
Jack Yu8a86b1f2019-01-30 16:21:45 +0800575 if (rw_i93_process_ext_sys_info(p, length)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200576 rw_data.i93_sys_info.status = NFC_STATUS_OK;
577 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
578 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
579 rw_data.i93_sys_info.afi = p_i93->afi;
580 rw_data.i93_sys_info.num_block = p_i93->num_block;
581 rw_data.i93_sys_info.block_size = p_i93->block_size;
582 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
583
584 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
585
586 event = RW_I93_SYS_INFO_EVT;
587 } else {
588 /* retrying with protocol extension flag or with extended sys info
589 * command */
590 p_i93->state = RW_I93_STATE_BUSY;
591 return;
592 }
593 break;
594
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800595 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800596 break;
597 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800598
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800599 rw_cb.tcb.i93.sent_cmd = 0;
600 if (event != RW_I93_MAX_EVT) {
601 (*(rw_cb.p_cback))(event, &rw_data);
602 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700603 LOG(ERROR) << StringPrintf("Invalid response");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800604 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800605}
606
607/*******************************************************************************
608**
609** Function rw_i93_send_to_lower
610**
611** Description Send Request frame to lower layer
612**
613** Returns TRUE if success
614**
615*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800616bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800617 /* store command for retransmitting */
618 if (rw_cb.tcb.i93.p_retry_cmd) {
619 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
620 rw_cb.tcb.i93.p_retry_cmd = NULL;
621 }
Evan Chu85b7e842013-01-18 11:02:50 -0500622
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800623 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
Evan Chu85b7e842013-01-18 11:02:50 -0500624
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800625 if (rw_cb.tcb.i93.p_retry_cmd) {
626 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
627 sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
628 }
Evan Chu85b7e842013-01-18 11:02:50 -0500629
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800630 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700631 LOG(ERROR) << StringPrintf("failed");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800632 return false;
633 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800634
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800635 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
636 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800637
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800638 return true;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800639}
640
641/*******************************************************************************
642**
643** Function rw_i93_send_cmd_inventory
644**
645** Description Send Inventory Request to VICC
646**
647** Returns tNFC_STATUS
648**
649*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800650tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
651 uint8_t afi) {
652 NFC_HDR* p_cmd;
653 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800654
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700655 DLOG_IF(INFO, nfc_debug_enabled)
656 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800657
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800658 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800659
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800660 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700661 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800662 return NFC_STATUS_NO_BUFFERS;
663 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800664
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800665 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
666 p_cmd->len = 3;
667 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800668
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800669 /* Flags */
670 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
671 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
672 if (including_afi) {
673 flags |= I93_FLAG_AFI_PRESENT;
674 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700675
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800676 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800677
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800678 /* Command Code */
679 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800680
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800681 if (including_afi) {
682 /* Parameters */
683 UINT8_TO_STREAM(p, afi); /* Optional AFI */
684 p_cmd->len++;
685 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700686
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800687 if (p_uid) {
688 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
689 ARRAY8_TO_STREAM(p, p_uid); /* UID */
690 p_cmd->len += I93_UID_BYTE_LEN;
691 } else {
692 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
693 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800694
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800695 if (rw_i93_send_to_lower(p_cmd)) {
696 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
697 return NFC_STATUS_OK;
698 } else {
699 return NFC_STATUS_FAILED;
700 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800701}
702
703/*******************************************************************************
704**
705** Function rw_i93_send_cmd_stay_quiet
706**
707** Description Send Stay Quiet Request to VICC
708**
709** Returns tNFC_STATUS
710**
711*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800712tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
713 NFC_HDR* p_cmd;
714 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800715
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700716 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800717
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800718 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800719
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800720 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700721 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800722 return NFC_STATUS_NO_BUFFERS;
723 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800724
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800725 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
726 p_cmd->len = 10;
727 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800728
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800729 /* Flags */
730 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
731 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800732
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800733 /* Command Code */
734 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800735
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800736 /* Parameters */
737 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800738
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800739 if (rw_i93_send_to_lower(p_cmd)) {
740 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800741
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800742 /* restart timer for stay quiet */
743 nfc_start_quick_timer(
744 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
745 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
746 return NFC_STATUS_OK;
747 } else {
748 return NFC_STATUS_FAILED;
749 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800750}
751
752/*******************************************************************************
753**
754** Function rw_i93_send_cmd_read_single_block
755**
756** Description Send Read Single Block Request to VICC
757**
758** Returns tNFC_STATUS
759**
760*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800761tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
762 bool read_security) {
763 NFC_HDR* p_cmd;
764 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800765
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700766 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800767
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800768 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800769
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800770 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700771 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800772 return NFC_STATUS_NO_BUFFERS;
773 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800775 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
776 p_cmd->len = 11;
777 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800778
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800779 /* Flags */
780 flags =
781 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500782
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800783 if (read_security) flags |= I93_FLAG_OPTION_SET;
Evan Chu85b7e842013-01-18 11:02:50 -0500784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800785 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
786 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500787
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800788 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800790 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200791 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
792 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_SINGLE_BLOCK);
793 } else {
794 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
795 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800796
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800797 /* Parameters */
798 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500799
Raphael Collado867d5c32017-03-27 12:49:40 +0200800 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
801 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800802 UINT16_TO_STREAM(p, block_number); /* Block number */
803 p_cmd->len++;
804 } else {
805 UINT8_TO_STREAM(p, block_number); /* Block number */
806 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800807
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800808 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200809 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
810 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_SINGLE_BLOCK;
811 else
812 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800813 return NFC_STATUS_OK;
814 } else {
815 return NFC_STATUS_FAILED;
816 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800817}
818
819/*******************************************************************************
820**
821** Function rw_i93_send_cmd_write_single_block
822**
823** Description Send Write Single Block Request to VICC
824**
825** Returns tNFC_STATUS
826**
827*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800828tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
829 uint8_t* p_data) {
830 NFC_HDR* p_cmd;
831 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800832
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700833 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800834
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800835 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800836
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800837 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700838 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800839 return NFC_STATUS_NO_BUFFERS;
840 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800841
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800842 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
843 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
844 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800845
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800846 /* Flags */
847 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
848 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
849 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
850 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
851 /* Option must be set for TI tag */
852 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
853 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
854 } else {
855 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
856 RW_I93_FLAG_DATA_RATE);
857 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800858
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800859 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
860 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -0500861
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800862 UINT8_TO_STREAM(p, flags);
Evan Chu85b7e842013-01-18 11:02:50 -0500863
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800864 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200865 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
866 UINT8_TO_STREAM(p, I93_CMD_EXT_WRITE_SINGLE_BLOCK);
867 } else {
868 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
869 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800870
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800871 /* Parameters */
872 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -0500873
Raphael Collado867d5c32017-03-27 12:49:40 +0200874 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
875 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800876 UINT16_TO_STREAM(p, block_number); /* Block number */
877 p_cmd->len++;
878 } else {
879 UINT8_TO_STREAM(p, block_number); /* Block number */
880 }
Evan Chu85b7e842013-01-18 11:02:50 -0500881
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800882 /* Data */
883 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800884
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800885 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200886 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
887 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_SINGLE_BLOCK;
888 else
889 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800890 return NFC_STATUS_OK;
891 } else {
892 return NFC_STATUS_FAILED;
893 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800894}
895
896/*******************************************************************************
897**
898** Function rw_i93_send_cmd_lock_block
899**
900** Description Send Lock Block Request to VICC
901**
Evan Chu85b7e842013-01-18 11:02:50 -0500902** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
903** do not support.
904**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800905** Returns tNFC_STATUS
906**
907*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800908tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
909 NFC_HDR* p_cmd;
910 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800911
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700912 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800913
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800914 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800915
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800916 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700917 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800918 return NFC_STATUS_NO_BUFFERS;
919 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800920
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800921 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
922 p_cmd->len = 11;
923 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800924
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800925 /* Flags */
926 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
927 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
928 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
929 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
930 /* Option must be set for TI tag */
931 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
932 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
933 } else {
934 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
935 RW_I93_FLAG_DATA_RATE));
936 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800937
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800938 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +0200939 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
940 UINT8_TO_STREAM(p, I93_CMD_EXT_LOCK_BLOCK);
941 } else {
942 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
943 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800944
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800945 /* Parameters */
946 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +0200947
948 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
949 UINT16_TO_STREAM(p, block_number); /* Block number */
950 p_cmd->len++;
951 } else {
952 UINT8_TO_STREAM(p, block_number); /* Block number */
953 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800954
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800955 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +0200956 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
957 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_LOCK_BLOCK;
958 else
959 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800960 return NFC_STATUS_OK;
961 } else {
962 return NFC_STATUS_FAILED;
963 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800964}
965
966/*******************************************************************************
967**
968** Function rw_i93_send_cmd_read_multi_blocks
969**
970** Description Send Read Multiple Blocks Request to VICC
971**
972** Returns tNFC_STATUS
973**
974*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800975tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
976 uint16_t number_blocks) {
977 NFC_HDR* p_cmd;
978 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800979
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700980 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800981
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800982 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800983
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800984 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -0700985 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800986 return NFC_STATUS_NO_BUFFERS;
987 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800988
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800989 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
990 p_cmd->len = 12;
991 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800992
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800993 /* Flags */
994 flags =
995 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -0500996
Raphael Collado867d5c32017-03-27 12:49:40 +0200997 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -0800998 flags |= I93_FLAG_PROT_EXT_YES;
Raphael Collado867d5c32017-03-27 12:49:40 +0200999 }
Evan Chu85b7e842013-01-18 11:02:50 -05001000
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001001 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001002
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001003 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001004 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1005 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_MULTI_BLOCK);
1006 } else {
1007 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
1008 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001009
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001010 /* Parameters */
1011 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001012
Raphael Collado867d5c32017-03-27 12:49:40 +02001013 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1014 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001015 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1016 p_cmd->len++;
1017 } else {
1018 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1019 }
Evan Chu85b7e842013-01-18 11:02:50 -05001020
Raphael Collado867d5c32017-03-27 12:49:40 +02001021 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1022 UINT16_TO_STREAM(
1023 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1024 p_cmd->len++;
1025 } else {
1026 UINT8_TO_STREAM(
1027 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1028 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001029
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001030 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001031 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1032 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_MULTI_BLOCK;
1033 else
1034 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001035 return NFC_STATUS_OK;
1036 } else {
1037 return NFC_STATUS_FAILED;
1038 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001039}
1040
1041/*******************************************************************************
1042**
1043** Function rw_i93_send_cmd_write_multi_blocks
1044**
1045** Description Send Write Multiple Blocks Request to VICC
1046**
1047** Returns tNFC_STATUS
1048**
1049*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02001050tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001051 uint16_t number_blocks,
1052 uint8_t* p_data) {
1053 NFC_HDR* p_cmd;
1054 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001055
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001056 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001057
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001058 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001059
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001060 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001061 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001062 return NFC_STATUS_NO_BUFFERS;
1063 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001064
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001065 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1066 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
1067 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001068
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001069 /* Flags */
1070 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1071 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001072
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001073 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001074 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1075 INT8_TO_STREAM(p, I93_CMD_EXT_WRITE_MULTI_BLOCK);
1076 } else {
1077 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
1078 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001079
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001080 /* Parameters */
1081 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Raphael Collado867d5c32017-03-27 12:49:40 +02001082 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1083 UINT16_TO_STREAM(p, first_block_number); /* Block number */
1084 UINT16_TO_STREAM(
1085 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1086 p_cmd->len += 2;
1087 } else {
1088 UINT8_TO_STREAM(p, first_block_number); /* Block number */
1089 UINT8_TO_STREAM(
1090 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1091 }
1092
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001093 UINT8_TO_STREAM(
1094 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001095
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001096 /* Data */
1097 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001098
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001099 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001100 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1101 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_MULTI_BLOCK;
1102 else
1103 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001104 return NFC_STATUS_OK;
1105 } else {
1106 return NFC_STATUS_FAILED;
1107 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001108}
1109
1110/*******************************************************************************
1111**
1112** Function rw_i93_send_cmd_select
1113**
1114** Description Send Select Request to VICC
1115**
1116** Returns tNFC_STATUS
1117**
1118*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001119tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1120 NFC_HDR* p_cmd;
1121 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001122
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001123 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001124
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001125 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001126
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001127 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001128 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001129 return NFC_STATUS_NO_BUFFERS;
1130 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001131
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001132 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1133 p_cmd->len = 10;
1134 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001135
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001136 /* Flags */
1137 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1138 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001139
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001140 /* Command Code */
1141 UINT8_TO_STREAM(p, I93_CMD_SELECT);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001142
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001143 /* Parameters */
1144 ARRAY8_TO_STREAM(p, p_uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001145
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001146 if (rw_i93_send_to_lower(p_cmd)) {
1147 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1148 return NFC_STATUS_OK;
1149 } else {
1150 return NFC_STATUS_FAILED;
1151 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001152}
1153
1154/*******************************************************************************
1155**
1156** Function rw_i93_send_cmd_reset_to_ready
1157**
1158** Description Send Reset to Ready Request to VICC
1159**
1160** Returns tNFC_STATUS
1161**
1162*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001163tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1164 NFC_HDR* p_cmd;
1165 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001166
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001167 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001168
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001169 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001170
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001171 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001172 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001173 return NFC_STATUS_NO_BUFFERS;
1174 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001175
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001176 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1177 p_cmd->len = 10;
1178 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001179
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001180 /* Flags */
1181 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1182 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001183
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001184 /* Command Code */
1185 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001186
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001187 /* Parameters */
1188 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001189
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001190 if (rw_i93_send_to_lower(p_cmd)) {
1191 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1192 return NFC_STATUS_OK;
1193 } else {
1194 return NFC_STATUS_FAILED;
1195 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001196}
1197
1198/*******************************************************************************
1199**
1200** Function rw_i93_send_cmd_write_afi
1201**
1202** Description Send Write AFI Request to VICC
1203**
1204** Returns tNFC_STATUS
1205**
1206*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001207tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1208 NFC_HDR* p_cmd;
1209 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001210
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001211 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001212
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001213 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001214
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001215 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001216 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001217 return NFC_STATUS_NO_BUFFERS;
1218 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001219
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001220 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1221 p_cmd->len = 11;
1222 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001223
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001224 /* Flags */
1225 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1226 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001227
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001228 /* Command Code */
1229 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001230
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001231 /* Parameters */
1232 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1233 UINT8_TO_STREAM(p, afi); /* AFI */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001234
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001235 if (rw_i93_send_to_lower(p_cmd)) {
1236 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1237 return NFC_STATUS_OK;
1238 } else {
1239 return NFC_STATUS_FAILED;
1240 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001241}
1242
1243/*******************************************************************************
1244**
1245** Function rw_i93_send_cmd_lock_afi
1246**
1247** Description Send Lock AFI Request to VICC
1248**
1249** Returns tNFC_STATUS
1250**
1251*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001252tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1253 NFC_HDR* p_cmd;
1254 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001255
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001256 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001257
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001258 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001259
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001260 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001261 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001262 return NFC_STATUS_NO_BUFFERS;
1263 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001264
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001265 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1266 p_cmd->len = 10;
1267 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001268
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001269 /* Flags */
1270 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1271 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001272
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001273 /* Command Code */
1274 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001275
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001276 /* Parameters */
1277 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001278
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001279 if (rw_i93_send_to_lower(p_cmd)) {
1280 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1281 return NFC_STATUS_OK;
1282 } else {
1283 return NFC_STATUS_FAILED;
1284 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001285}
1286
1287/*******************************************************************************
1288**
1289** Function rw_i93_send_cmd_write_dsfid
1290**
1291** Description Send Write DSFID Request to VICC
1292**
1293** Returns tNFC_STATUS
1294**
1295*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001296tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1297 NFC_HDR* p_cmd;
1298 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001299
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001300 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001301
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001302 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001303
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001304 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001305 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001306 return NFC_STATUS_NO_BUFFERS;
1307 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001308
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001309 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1310 p_cmd->len = 11;
1311 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001312
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001313 /* Flags */
1314 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1315 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001316
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001317 /* Command Code */
1318 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001319
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001320 /* Parameters */
1321 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1322 UINT8_TO_STREAM(p, dsfid); /* DSFID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001323
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001324 if (rw_i93_send_to_lower(p_cmd)) {
1325 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1326 return NFC_STATUS_OK;
1327 } else {
1328 return NFC_STATUS_FAILED;
1329 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001330}
1331
1332/*******************************************************************************
1333**
1334** Function rw_i93_send_cmd_lock_dsfid
1335**
1336** Description Send Lock DSFID Request to VICC
1337**
1338** Returns tNFC_STATUS
1339**
1340*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001341tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1342 NFC_HDR* p_cmd;
1343 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001344
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001345 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001346
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001347 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001348
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001349 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001350 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001351 return NFC_STATUS_NO_BUFFERS;
1352 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001353
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001354 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1355 p_cmd->len = 10;
1356 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001357
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001358 /* Flags */
1359 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1360 RW_I93_FLAG_DATA_RATE));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001361
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001362 /* Command Code */
1363 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001364
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001365 /* Parameters */
1366 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001367
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001368 if (rw_i93_send_to_lower(p_cmd)) {
1369 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1370 return NFC_STATUS_OK;
1371 } else {
1372 return NFC_STATUS_FAILED;
1373 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001374}
1375
1376/*******************************************************************************
1377**
Raphael Collado867d5c32017-03-27 12:49:40 +02001378** Function rw_i93_send_cmd_get_ext_sys_info
1379**
1380** Description Send Get Extended System Information Request to VICC
1381**
1382** Returns tNFC_STATUS
1383**
1384*******************************************************************************/
1385tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid) {
1386 NFC_HDR* p_cmd;
1387 uint8_t* p;
1388
1389 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1390
1391 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1392
1393 if (!p_cmd) {
1394 DLOG_IF(INFO, nfc_debug_enabled) << __func__ << "Cannot allocate buffer";
1395 return NFC_STATUS_NO_BUFFERS;
1396 }
1397
1398 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1399 p_cmd->len = 11;
1400 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1401
1402 /* Flags */
1403 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1404 RW_I93_FLAG_DATA_RATE));
1405
1406 /* Command Code */
1407 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_SYS_INFO);
1408
1409 /* Parameters request field */
1410 UINT8_TO_STREAM(p,
1411 (I93_INFO_FLAG_MOI | I93_INFO_FLAG_DSFID | I93_INFO_FLAG_AFI |
1412 I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_IC_REF));
1413
1414 /* Parameters */
1415 if (p_uid) {
1416 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1417 } else {
1418 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1419 }
1420
1421 if (rw_i93_send_to_lower(p_cmd)) {
1422 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_SYS_INFO;
1423 return NFC_STATUS_OK;
1424 } else {
1425 return NFC_STATUS_FAILED;
1426 }
1427}
1428
1429/*******************************************************************************
1430**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001431** Function rw_i93_send_cmd_get_sys_info
1432**
1433** Description Send Get System Information Request to VICC
1434**
1435** Returns tNFC_STATUS
1436**
1437*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001438tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1439 NFC_HDR* p_cmd;
1440 uint8_t* p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001441
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001442 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001443
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001444 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001445
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001446 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001447 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001448 return NFC_STATUS_NO_BUFFERS;
1449 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001450
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001451 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1452 p_cmd->len = 10;
1453 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001454
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001455 /* Flags */
1456 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1457 RW_I93_FLAG_DATA_RATE | extra_flags));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001458
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001459 /* Command Code */
1460 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001461
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001462 /* Parameters */
1463 if (p_uid) {
1464 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1465 } else {
1466 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1467 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001468
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001469 if (rw_i93_send_to_lower(p_cmd)) {
1470 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1471 return NFC_STATUS_OK;
1472 } else {
1473 return NFC_STATUS_FAILED;
1474 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001475}
1476
1477/*******************************************************************************
1478**
1479** Function rw_i93_send_cmd_get_multi_block_sec
1480**
1481** Description Send Get Multiple Block Security Status Request to VICC
1482**
1483** Returns tNFC_STATUS
1484**
1485*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001486tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1487 uint16_t number_blocks) {
1488 NFC_HDR* p_cmd;
1489 uint8_t *p, flags;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001490
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001491 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001492
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001493 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001494
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001495 if (!p_cmd) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001496 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001497 return NFC_STATUS_NO_BUFFERS;
1498 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001499
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001500 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1501 p_cmd->len = 12;
1502 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001503
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001504 /* Flags */
1505 flags =
1506 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
Evan Chu85b7e842013-01-18 11:02:50 -05001507
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001508 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1509 flags |= I93_FLAG_PROT_EXT_YES;
Evan Chu85b7e842013-01-18 11:02:50 -05001510
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001511 UINT8_TO_STREAM(p, flags);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001512
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001513 /* Command Code */
Raphael Collado867d5c32017-03-27 12:49:40 +02001514 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1515 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_MULTI_BLK_SEC);
1516 } else {
1517 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1518 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001519
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001520 /* Parameters */
1521 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
Evan Chu85b7e842013-01-18 11:02:50 -05001522
Raphael Collado867d5c32017-03-27 12:49:40 +02001523 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1524 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001525 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1526 UINT16_TO_STREAM(
1527 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1528 p_cmd->len += 2;
1529 } else {
1530 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1531 UINT8_TO_STREAM(
1532 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1533 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001534
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001535 if (rw_i93_send_to_lower(p_cmd)) {
Raphael Collado867d5c32017-03-27 12:49:40 +02001536 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1537 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_MULTI_BLK_SEC;
1538 else
1539 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001540 return NFC_STATUS_OK;
1541 } else {
1542 return NFC_STATUS_FAILED;
1543 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001544}
1545
1546/*******************************************************************************
1547**
1548** Function rw_i93_get_next_blocks
1549**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001550** Description Read as many blocks as possible (up to
1551** RW_I93_READ_MULTI_BLOCK_SIZE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001552**
1553** Returns tNFC_STATUS
1554**
1555*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001556tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1557 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1558 uint16_t first_block;
1559 uint16_t num_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001560
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001561 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001562
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001563 first_block = offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001564
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001565 /* more blocks, more efficent but more error rate */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001566
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001567 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1568 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001569
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001570 if (num_block + first_block > p_i93->num_block)
1571 num_block = p_i93->num_block - first_block;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001572
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001573 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
1574 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1575 ** - The max number of blocks is 32 and they are all located in the
1576 ** same sector.
1577 ** - The sector is 32 blocks of 4 bytes.
1578 */
1579 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1580 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1581 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1582 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
1583 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1584 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1585 num_block = I93_STM_MAX_BLOCKS_PER_READ;
Evan Chu85b7e842013-01-18 11:02:50 -05001586
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001587 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1588 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1589 num_block = I93_STM_BLOCKS_PER_SECTOR -
1590 (first_block % I93_STM_BLOCKS_PER_SECTOR);
Evan Chu85b7e842013-01-18 11:02:50 -05001591 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001592 }
1593 }
Evan Chu85b7e842013-01-18 11:02:50 -05001594
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001595 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1596 } else {
1597 return rw_i93_send_cmd_read_single_block(first_block, false);
1598 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001599}
1600
1601/*******************************************************************************
1602**
Evan Chu85b7e842013-01-18 11:02:50 -05001603** Function rw_i93_get_next_block_sec
1604**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001605** Description Get as many security of blocks as possible from
1606** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
Evan Chu85b7e842013-01-18 11:02:50 -05001607**
1608** Returns tNFC_STATUS
1609**
1610*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001611tNFC_STATUS rw_i93_get_next_block_sec(void) {
1612 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1613 uint16_t num_blocks;
Evan Chu85b7e842013-01-18 11:02:50 -05001614
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001615 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
Evan Chu85b7e842013-01-18 11:02:50 -05001616
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001617 if (p_i93->num_block <= p_i93->rw_offset) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001618 LOG(ERROR) << StringPrintf(
1619 "rw_offset(0x%x) must be less than num_block(0x%x)", p_i93->rw_offset,
1620 p_i93->num_block);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001621 return NFC_STATUS_FAILED;
1622 }
Evan Chu85b7e842013-01-18 11:02:50 -05001623
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001624 num_blocks = p_i93->num_block - p_i93->rw_offset;
Evan Chu85b7e842013-01-18 11:02:50 -05001625
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001626 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1627 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
Evan Chu85b7e842013-01-18 11:02:50 -05001628
Raphael Collado867d5c32017-03-27 12:49:40 +02001629 DLOG_IF(INFO, nfc_debug_enabled)
1630 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001631 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
Evan Chu85b7e842013-01-18 11:02:50 -05001632}
1633
1634/*******************************************************************************
1635**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001636** Function rw_i93_sm_detect_ndef
1637**
1638** Description Process NDEF detection procedure
1639**
1640** 1. Get UID if not having yet
1641** 2. Get System Info if not having yet
1642** 3. Read first block for CC
1643** 4. Search NDEF Type and length
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08001644** 5. Get block status to get max NDEF size and read-only
1645** status
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001646**
1647** Returns void
1648**
1649*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001650void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07001651 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001652 uint8_t flags, u8 = 0, cc[4];
1653 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1654 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1655 tRW_DATA rw_data;
1656 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001657
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001658 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1659 "sub_state:%s (0x%x)",
1660 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 -08001661
Ruchi Kandoi6e267b32019-01-24 13:39:18 -08001662 if (length == 0) {
1663 android_errorWriteLog(0x534e4554, "121260197");
1664 rw_i93_handle_error(NFC_STATUS_FAILED);
1665 return;
1666 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001667 STREAM_TO_UINT8(flags, p);
1668 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001669
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001670 if (flags & I93_FLAG_ERROR_DETECTED) {
1671 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1672 /* getting system info with protocol extension flag */
1673 /* This STM tag supports more than 2040 bytes */
1674 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1675 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001676 DLOG_IF(INFO, nfc_debug_enabled)
1677 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001678 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001679 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001680 return;
1681 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001683 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001684 case RW_I93_SUBSTATE_WAIT_UID:
1685
Ruchi Kandoi6e267b32019-01-24 13:39:18 -08001686 if (length < (I93_UID_BYTE_LEN + 1)) {
1687 android_errorWriteLog(0x534e4554, "121260197");
1688 rw_i93_handle_error(NFC_STATUS_FAILED);
1689 return;
1690 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001691 STREAM_TO_UINT8(u8, p); /* DSFID */
1692 p_uid = p_i93->uid;
1693 STREAM_TO_ARRAY8(p_uid, p);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001694
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001695 if (u8 != I93_DFS_UNSUPPORTED) {
1696 /* if Data Storage Format is unknown */
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001697 DLOG_IF(INFO, nfc_debug_enabled)
1698 << StringPrintf("Got unknown DSFID (0x%02x)", u8);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001699 rw_i93_handle_error(NFC_STATUS_FAILED);
1700 } else {
1701 /* get system information to get memory size */
1702 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
1703 NFC_STATUS_OK) {
1704 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1705 } else {
1706 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001707 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001708 }
1709 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001710
1711 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1712
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001713 p_i93->block_size = 0;
1714 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001715
Ruchi Kandoiba95bb12019-01-24 14:45:55 -08001716 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001717 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001718 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001719 }
1720
1721 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001722 DLOG_IF(INFO, nfc_debug_enabled)
1723 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001724 rw_i93_handle_error(status);
1725 } else {
1726 /* read CC in the first block */
1727 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1728 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1729 } else {
1730 rw_i93_handle_error(NFC_STATUS_FAILED);
1731 }
1732 }
1733 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001734
1735 case RW_I93_SUBSTATE_WAIT_CC:
1736
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001737 /* assume block size is more than 4 */
1738 STREAM_TO_ARRAY(cc, p, 4);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001739
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001740 status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001741
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001742 /*
1743 ** Capability Container (CC)
1744 **
1745 ** CC[0] : magic number (0xE1)
1746 ** CC[1] : Bit 7-6:Major version number
1747 ** : Bit 5-4:Minor version number
1748 ** : Bit 3-2:Read access condition (00b: read access granted
1749 ** without any security)
1750 ** : Bit 1-0:Write access condition (00b: write access granted
1751 ** without any security)
1752 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
1753 ** 0xFF if more than 2040bytes]
1754 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1755 ** : Bit 1:Inventory page read is supported [NXP]
1756 ** : Bit 2:More than 2040 bytes are supported [STM]
1757 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001758
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001759 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1760 "cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
1761 DLOG_IF(INFO, nfc_debug_enabled)
1762 << StringPrintf("Total blocks:0x%04X, Block size:0x%02X",
1763 p_i93->num_block, p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001764
Raphael Collado867d5c32017-03-27 12:49:40 +02001765 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1766 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001767 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1768 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1769 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1770 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1771 /* read-only or password required to write */
1772 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1773 }
1774 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
1775 /* tag supports read multi blocks command */
1776 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1777 }
Raphael Collado867d5c32017-03-27 12:49:40 +02001778 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1779 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1780 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001781 status = NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001782 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001783 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001784
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001785 if (status == NFC_STATUS_OK) {
1786 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1787 */
1788 if (cc[2] != 0)
1789 p_i93->rw_offset = 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001790 else
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001791 p_i93->rw_offset = 8;
1792
1793 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1794 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1795 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1796 } else {
1797 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001798 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001799 } else {
1800 rw_i93_handle_error(NFC_STATUS_FAILED);
1801 }
1802 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001803
1804 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1805
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001806 /* search TLV within read blocks */
1807 for (xx = 0; xx < length; xx++) {
1808 /* if looking for type */
1809 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1810 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1811 continue;
1812 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1813 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1814 /* store found type and get length field */
1815 p_i93->tlv_type = *(p + xx);
1816 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001817
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001818 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1819 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1820 /* no NDEF TLV found */
1821 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1822 break;
1823 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07001824 DLOG_IF(INFO, nfc_debug_enabled)
1825 << StringPrintf("Invalid type: 0x%02x", *(p + xx));
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001826 rw_i93_handle_error(NFC_STATUS_FAILED);
1827 return;
1828 }
1829 } else if (p_i93->tlv_detect_state ==
1830 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
1831 /* if 3 bytes length field */
1832 if (*(p + xx) == 0xFF) {
1833 /* need 2 more bytes for length field */
1834 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1835 } else {
1836 p_i93->tlv_length = *(p + xx);
1837 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1838
1839 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1840 p_i93->ndef_tlv_last_offset =
1841 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1842 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001843 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001844 }
1845 } else if (p_i93->tlv_detect_state ==
1846 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
1847 /* the second byte of 3 bytes length field */
1848 p_i93->tlv_length = *(p + xx);
1849 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1850 } else if (p_i93->tlv_detect_state ==
1851 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
1852 /* the last byte of 3 bytes length field */
1853 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
1854 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001855
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001856 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1857 p_i93->ndef_tlv_last_offset =
1858 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1859 break;
1860 }
1861 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
1862 /* this is other than NDEF TLV */
1863 if (p_i93->tlv_length <= length - xx) {
1864 /* skip value field */
1865 xx += (uint8_t)p_i93->tlv_length;
1866 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1867 } else {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001868 /* read more data */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001869 p_i93->tlv_length -= (length - xx);
1870 break;
1871 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001872 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001873 }
1874
1875 /* found NDEF TLV and read length field */
1876 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
1877 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
1878 p_i93->ndef_length = p_i93->tlv_length;
1879
1880 /* get lock status to see if read-only */
1881 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1882 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1883 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1884 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1885 /* these doesn't support GetMultiBlockSecurityStatus */
1886
1887 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
1888 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
1889
1890 /* read block to get lock status */
1891 rw_i93_send_cmd_read_single_block(first_block, true);
1892 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1893 } else {
1894 /* block offset for read-only check */
1895 p_i93->rw_offset = 0;
1896
1897 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
1898 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1899 } else {
1900 rw_i93_handle_error(NFC_STATUS_FAILED);
1901 }
1902 }
1903 } else {
1904 /* read more data */
1905 p_i93->rw_offset += length;
1906
1907 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
1908 rw_i93_handle_error(NFC_STATUS_FAILED);
1909 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1910 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1911 } else {
1912 rw_i93_handle_error(NFC_STATUS_FAILED);
1913 }
1914 }
1915 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001916
1917 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1918
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001919 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1920 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1921 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1922 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1923 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001924
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001925 block = (p_i93->rw_offset / p_i93->block_size);
1926 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001927
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001928 if ((*p) & I93_BLOCK_LOCKED) {
1929 if (block <= last_block) {
1930 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1931 }
1932 } else {
1933 /* if we need to check more user blocks */
1934 if (block + 1 < p_i93->num_block) {
1935 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001936
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001937 /* read block to get lock status */
1938 rw_i93_send_cmd_read_single_block(
1939 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
1940 break;
1941 }
Evan Chu85b7e842013-01-18 11:02:50 -05001942 }
1943
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001944 p_i93->max_ndef_length =
1945 p_i93->ndef_length
1946 /* add available bytes including the last block of NDEF TLV */
1947 + (p_i93->block_size * (block - last_block) + 1) -
1948 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1949 } else {
1950 if (p_i93->rw_offset == 0) {
1951 p_i93->max_ndef_length =
1952 p_i93->ndef_length
1953 /* add available bytes in the last block of NDEF TLV */
1954 + p_i93->block_size -
1955 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1956
1957 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1958 } else {
1959 first_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001960 }
1961
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001962 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1963 num_blocks = length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001964
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001965 for (block = first_block; block < num_blocks; block++) {
1966 /* if any block of NDEF TLV is locked */
1967 if ((block + p_i93->rw_offset) <= last_block) {
1968 if (*(p + block) & I93_BLOCK_LOCKED) {
1969 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1970 break;
1971 }
1972 } else {
1973 if (*(p + block) & I93_BLOCK_LOCKED) {
1974 /* no more consecutive unlocked block */
1975 break;
1976 } else {
1977 /* add block size if not locked */
1978 p_i93->max_ndef_length += p_i93->block_size;
1979 }
1980 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001981 }
1982
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001983 /* update next security of block to check */
1984 p_i93->rw_offset += num_blocks;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001985
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001986 /* if need to check more */
1987 if (p_i93->num_block > p_i93->rw_offset) {
1988 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
1989 rw_i93_handle_error(NFC_STATUS_FAILED);
1990 }
1991 break;
1992 }
1993 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001994
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08001995 /* check if need to adjust max NDEF length */
1996 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
1997 /* 3 bytes length field must be used */
1998 p_i93->max_ndef_length -= 2;
1999 }
2000
2001 rw_data.ndef.status = NFC_STATUS_OK;
Love Khanna57a3dfa2017-03-28 20:03:38 +05302002 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002003 rw_data.ndef.flags = 0;
2004 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
2005 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
2006 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2007 rw_data.ndef.cur_size = p_i93->ndef_length;
2008
2009 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
2010 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
2011 rw_data.ndef.max_size = p_i93->ndef_length;
2012 } else {
2013 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
2014 rw_data.ndef.max_size = p_i93->max_ndef_length;
2015 }
2016
2017 p_i93->state = RW_I93_STATE_IDLE;
2018 p_i93->sent_cmd = 0;
2019
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002020 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2021 "NDEF cur_size(%d),max_size (%d), flags (0x%x)",
2022 rw_data.ndef.cur_size, rw_data.ndef.max_size, rw_data.ndef.flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002023
2024 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
2025 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002026
2027 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002028 break;
2029 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002030}
2031
2032/*******************************************************************************
2033**
2034** Function rw_i93_sm_read_ndef
2035**
2036** Description Process NDEF read procedure
2037**
2038** Returns void
2039**
2040*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002041void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
2042 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2043 uint8_t flags;
2044 uint16_t offset, length = p_resp->len;
2045 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2046 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002047
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002048 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002049
Jack Yu46defd32019-01-30 14:59:09 +08002050 if (length == 0) {
2051 android_errorWriteLog(0x534e4554, "122035770");
2052 rw_i93_handle_error(NFC_STATUS_FAILED);
2053 return;
2054 }
2055
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002056 STREAM_TO_UINT8(flags, p);
2057 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002058
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002059 if (flags & I93_FLAG_ERROR_DETECTED) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002060 DLOG_IF(INFO, nfc_debug_enabled)
2061 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002062 rw_i93_handle_error(NFC_STATUS_FAILED);
2063 return;
2064 }
2065
2066 /* if this is the first block */
2067 if (p_i93->rw_length == 0) {
2068 /* get start of NDEF in the first block */
2069 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
2070
2071 if (p_i93->ndef_length < 0xFF) {
2072 offset += 2;
2073 } else {
2074 offset += 4;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002075 }
2076
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002077 /* adjust offset if read more blocks because the first block doesn't have
2078 * NDEF */
2079 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
2080 } else {
2081 offset = 0;
2082 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002083
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002084 /* if read enough data to skip type and length field for the beginning */
2085 if (offset < length) {
2086 offset++; /* flags */
2087 p_resp->offset += offset;
2088 p_resp->len -= offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002089
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002090 rw_data.data.status = NFC_STATUS_OK;
2091 rw_data.data.p_data = p_resp;
2092
2093 p_i93->rw_length += p_resp->len;
2094 } else {
2095 /* in case of no Ndef data included */
2096 p_resp->len = 0;
2097 }
2098
2099 /* if read all of NDEF data */
2100 if (p_i93->rw_length >= p_i93->ndef_length) {
2101 /* remove extra btyes in the last block */
2102 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2103
2104 p_i93->state = RW_I93_STATE_IDLE;
2105 p_i93->sent_cmd = 0;
2106
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002107 DLOG_IF(INFO, nfc_debug_enabled)
2108 << StringPrintf("NDEF read complete read (%d)/total (%d)", p_resp->len,
2109 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002110
2111 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2112 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002113 DLOG_IF(INFO, nfc_debug_enabled)
2114 << StringPrintf("NDEF read segment read (%d)/total (%d)", p_resp->len,
2115 p_i93->ndef_length);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002116
2117 if (p_resp->len > 0) {
2118 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002119 }
2120
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002121 /* this will make read data from next block */
2122 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002123
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002124 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2125 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002126 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002127 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002128}
2129
2130/*******************************************************************************
2131**
2132** Function rw_i93_sm_update_ndef
2133**
2134** Description Process NDEF update procedure
2135**
2136** 1. Set length field to zero
2137** 2. Write NDEF and Terminator TLV
2138** 3. Set length field to NDEF length
2139**
2140** Returns void
2141**
2142*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002143void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
2144 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2145 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2146 uint16_t length = p_resp->len, block_number;
2147 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2148 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002149
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002150 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2151 "sub_state:%s (0x%x)",
2152 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 -08002153
Jack Yu9b406b62019-01-30 15:10:07 +08002154 if (length == 0 || p_i93->block_size > I93_MAX_BLOCK_LENGH) {
2155 android_errorWriteLog(0x534e4554, "122320256");
2156 rw_i93_handle_error(NFC_STATUS_FAILED);
2157 return;
2158 }
2159
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002160 STREAM_TO_UINT8(flags, p);
2161 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002162
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002163 if (flags & I93_FLAG_ERROR_DETECTED) {
2164 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2165 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2166 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2167 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2168 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2169 /* ignore error */
2170 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002171 DLOG_IF(INFO, nfc_debug_enabled)
2172 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002173 rw_i93_handle_error(NFC_STATUS_FAILED);
2174 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002175 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002176 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002177
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002178 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002179 case RW_I93_SUBSTATE_RESET_LEN:
2180
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002181 /* get offset of length field */
2182 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002183
Jack Yu9b406b62019-01-30 15:10:07 +08002184 if (length < length_offset) {
2185 android_errorWriteLog(0x534e4554, "122320256");
2186 rw_i93_handle_error(NFC_STATUS_FAILED);
2187 return;
2188 }
2189
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002190 /* set length to zero */
2191 *(p + length_offset) = 0x00;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002192
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002193 if (p_i93->ndef_length > 0) {
2194 /* if 3 bytes length field is needed */
2195 if (p_i93->ndef_length >= 0xFF) {
2196 xx = length_offset + 3;
2197 } else {
2198 xx = length_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002199 }
2200
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002201 /* write the first part of NDEF in the same block */
2202 for (; xx < p_i93->block_size; xx++) {
Jack Yu9b406b62019-01-30 15:10:07 +08002203 if (xx > length || p_i93->rw_length > p_i93->ndef_length) {
2204 android_errorWriteLog(0x534e4554, "122320256");
2205 rw_i93_handle_error(NFC_STATUS_FAILED);
2206 return;
2207 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002208 if (p_i93->rw_length < p_i93->ndef_length) {
2209 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2210 } else {
2211 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2212 }
2213 }
2214 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002215
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002216 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2217
2218 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2219 NFC_STATUS_OK) {
2220 /* update next writing offset */
2221 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2222 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2223 } else {
2224 rw_i93_handle_error(NFC_STATUS_FAILED);
2225 }
2226 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002227
2228 case RW_I93_SUBSTATE_WRITE_NDEF:
2229
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002230 /* if it's not the end of tag memory */
2231 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
2232 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002233
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002234 /* if we have more data to write */
2235 if (p_i93->rw_length < p_i93->ndef_length) {
2236 p = p_i93->p_update_data + p_i93->rw_length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002237
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002238 p_i93->rw_offset += p_i93->block_size;
2239 p_i93->rw_length += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002240
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002241 /* if this is the last block of NDEF TLV */
2242 if (p_i93->rw_length > p_i93->ndef_length) {
2243 /* length of NDEF TLV in the block */
2244 xx = (uint8_t)(p_i93->block_size -
2245 (p_i93->rw_length - p_i93->ndef_length));
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002246
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002247 /* set NULL TLV in the unused part of block */
2248 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2249 memcpy(buff, p, xx);
2250 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002251
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002252 /* if it's the end of tag memory */
2253 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2254 (xx < p_i93->block_size)) {
2255 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002256 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002257
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002258 p_i93->ndef_tlv_last_offset =
2259 p_i93->rw_offset - p_i93->block_size + xx - 1;
2260 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002261
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002262 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2263 NFC_STATUS_OK) {
2264 rw_i93_handle_error(NFC_STATUS_FAILED);
2265 }
2266 } else {
2267 /* if this is the very next block of NDEF TLV */
2268 if (block_number ==
2269 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2270 p_i93->rw_offset += p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002271
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002272 /* write Terminator TLV and NULL TLV */
2273 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2274 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2275 p = buff;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002276
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002277 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2278 NFC_STATUS_OK) {
2279 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002280 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002281 } else {
2282 /* finished writing NDEF and Terminator TLV */
2283 /* read length field to update length */
2284 block_number =
2285 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2286
2287 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2288 NFC_STATUS_OK) {
2289 /* set offset to length field */
2290 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2291
2292 /* get size of length field */
2293 if (p_i93->ndef_length >= 0xFF) {
2294 p_i93->rw_length = 3;
2295 } else if (p_i93->ndef_length > 0) {
2296 p_i93->rw_length = 1;
2297 } else {
2298 p_i93->rw_length = 0;
2299 }
2300
2301 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2302 } else {
2303 rw_i93_handle_error(NFC_STATUS_FAILED);
2304 }
2305 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002306 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002307 } else {
2308 /* if we have no more data to write */
2309 if (p_i93->rw_length >= p_i93->ndef_length) {
2310 /* finished writing NDEF and Terminator TLV */
2311 /* read length field to update length */
2312 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002313
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002314 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2315 NFC_STATUS_OK) {
2316 /* set offset to length field */
2317 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002318
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002319 /* get size of length field */
2320 if (p_i93->ndef_length >= 0xFF) {
2321 p_i93->rw_length = 3;
2322 } else if (p_i93->ndef_length > 0) {
2323 p_i93->rw_length = 1;
2324 } else {
2325 p_i93->rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002326 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002327
2328 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2329 break;
2330 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002331 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002332 rw_i93_handle_error(NFC_STATUS_FAILED);
2333 }
2334 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002335
2336 case RW_I93_SUBSTATE_UPDATE_LEN:
2337
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002338 /* if we have more length field to write */
2339 if (p_i93->rw_length > 0) {
2340 /* if we got ack for writing, read next block to update rest of length
2341 * field */
2342 if (length == 0) {
2343 block_number = p_i93->rw_offset / p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002344
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002345 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2346 NFC_STATUS_OK) {
2347 rw_i93_handle_error(NFC_STATUS_FAILED);
2348 }
2349 } else {
2350 length_offset = p_i93->rw_offset % p_i93->block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002351
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002352 /* update length field within the read block */
2353 for (xx = length_offset; xx < p_i93->block_size; xx++) {
Jack Yu9b406b62019-01-30 15:10:07 +08002354 if (xx > length) {
2355 android_errorWriteLog(0x534e4554, "122320256");
2356 rw_i93_handle_error(NFC_STATUS_FAILED);
2357 return;
2358 }
2359
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002360 if (p_i93->rw_length == 3)
2361 *(p + xx) = 0xFF;
2362 else if (p_i93->rw_length == 2)
2363 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2364 else if (p_i93->rw_length == 1)
2365 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002366
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002367 p_i93->rw_length--;
2368 if (p_i93->rw_length == 0) break;
2369 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002370
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002371 block_number = (p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002372
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002373 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2374 NFC_STATUS_OK) {
2375 /* set offset to the beginning of next block */
2376 p_i93->rw_offset +=
2377 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2378 } else {
2379 rw_i93_handle_error(NFC_STATUS_FAILED);
2380 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002381 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002382 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002383 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2384 "NDEF update complete, %d bytes, (%d-%d)", p_i93->ndef_length,
2385 p_i93->ndef_tlv_start_offset, p_i93->ndef_tlv_last_offset);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002386
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002387 p_i93->state = RW_I93_STATE_IDLE;
2388 p_i93->sent_cmd = 0;
2389 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002390
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002391 rw_data.status = NFC_STATUS_OK;
2392 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2393 }
2394 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002395
2396 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002397 break;
2398 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002399}
2400
2401/*******************************************************************************
2402**
2403** Function rw_i93_sm_format
2404**
2405** Description Process format procedure
2406**
2407** 1. Get UID
2408** 2. Get sys info for memory size (reset AFI/DSFID)
2409** 3. Get block status to get read-only status
2410** 4. Write CC and empty NDEF
2411**
2412** Returns void
2413**
2414*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002415void rw_i93_sm_format(NFC_HDR* p_resp) {
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07002416 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002417 uint8_t flags;
2418 uint16_t length = p_resp->len, xx, block_number;
2419 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2420 tRW_DATA rw_data;
2421 tNFC_STATUS status = NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002422
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002423 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2424 "sub_state:%s (0x%x)",
2425 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 -08002426
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002427 STREAM_TO_UINT8(flags, p);
2428 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002429
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002430 if (flags & I93_FLAG_ERROR_DETECTED) {
2431 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2432 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2433 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2434 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2435 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2436 /* ignore error */
2437 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2438 /* getting system info with protocol extension flag */
2439 /* This STM tag supports more than 2040 bytes */
2440 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2441 return;
2442 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002443 DLOG_IF(INFO, nfc_debug_enabled)
2444 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002445 rw_i93_handle_error(NFC_STATUS_FAILED);
2446 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002447 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002448 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002449
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002450 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002451 case RW_I93_SUBSTATE_WAIT_UID:
2452
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002453 p++; /* skip DSFID */
2454 p_uid = p_i93->uid;
2455 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002456
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002457 /* get system information to get memory size */
2458 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
2459 NFC_STATUS_OK) {
2460 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2461 } else {
2462 rw_i93_handle_error(NFC_STATUS_FAILED);
2463 }
2464 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002465
2466 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2467
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002468 p_i93->block_size = 0;
2469 p_i93->num_block = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002470
Ruchi Kandoiba95bb12019-01-24 14:45:55 -08002471 if (!rw_i93_process_sys_info(p, length)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002472 /* retrying with protocol extension flag */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002473 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002474 }
2475
2476 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2477 /* DSFID, if any DSFID then reset */
2478 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2479 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2480 }
2481 }
2482 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2483 /* AFI, reset to 0 */
2484 if (p_i93->afi != 0x00) {
2485 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2486 }
2487 }
2488
2489 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002490 DLOG_IF(INFO, nfc_debug_enabled)
2491 << StringPrintf("Unable to get tag memory size");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002492 rw_i93_handle_error(status);
2493 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2494 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2495 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2496 } else {
2497 rw_i93_handle_error(NFC_STATUS_FAILED);
2498 }
2499 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2500 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2501 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2502 } else {
2503 rw_i93_handle_error(NFC_STATUS_FAILED);
2504 }
2505 } else {
2506 /* get lock status to see if read-only */
2507 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2508 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2509 /* these doesn't support GetMultiBlockSecurityStatus */
2510
2511 rw_cb.tcb.i93.rw_offset = 0;
2512
2513 /* read blocks with option flag to get block security status */
2514 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2515 NFC_STATUS_OK) {
2516 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2517 } else {
2518 rw_i93_handle_error(NFC_STATUS_FAILED);
2519 }
2520 } else {
2521 /* block offset for read-only check */
2522 p_i93->rw_offset = 0;
2523
2524 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2525 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2526 } else {
2527 rw_i93_handle_error(NFC_STATUS_FAILED);
2528 }
2529 }
2530 }
2531
2532 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002533
2534 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2535
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002536 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2537 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2538 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2539 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2540 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002541
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002542 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2543 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2544 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2545 } else {
2546 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002547 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002548 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2549 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2550 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2551 } else {
2552 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002553 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002554 } else {
2555 /* get lock status to see if read-only */
2556 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2557 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2558 /* these doesn't support GetMultiBlockSecurityStatus */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002559
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002560 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002561
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002562 /* read blocks with option flag to get block security status */
2563 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2564 NFC_STATUS_OK) {
2565 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2566 } else {
2567 rw_i93_handle_error(NFC_STATUS_FAILED);
2568 }
2569 } else {
2570 /* block offset for read-only check */
2571 p_i93->rw_offset = 0;
Evan Chu85b7e842013-01-18 11:02:50 -05002572
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002573 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2574 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2575 } else {
2576 rw_i93_handle_error(NFC_STATUS_FAILED);
2577 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002578 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002579 }
2580 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002581
2582 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2583
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002584 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2585 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2586 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2587 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2588 if ((*p) & I93_BLOCK_LOCKED) {
2589 rw_i93_handle_error(NFC_STATUS_FAILED);
2590 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002591 }
2592
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002593 /* if we checked all of user blocks */
2594 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2595 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2596 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2597 /* read the block which has AFI */
2598 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2599 rw_i93_send_cmd_read_single_block(
2600 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002601 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002602 }
2603 } else if (p_i93->rw_offset ==
2604 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2605 /* no block is locked */
2606 } else {
2607 p_i93->rw_offset += p_i93->block_size;
2608 rw_i93_send_cmd_read_single_block(
2609 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2610 break;
2611 }
2612 } else {
2613 /* if any block is locked, we cannot format it */
2614 for (xx = 0; xx < length; xx++) {
2615 if (*(p + xx) & I93_BLOCK_LOCKED) {
2616 rw_i93_handle_error(NFC_STATUS_FAILED);
2617 break;
2618 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002619 }
2620
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002621 /* update block offset for read-only check */
2622 p_i93->rw_offset += length;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002623
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002624 /* if need to get more lock status of blocks */
2625 if (p_i93->num_block > p_i93->rw_offset) {
2626 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2627 rw_i93_handle_error(NFC_STATUS_FAILED);
2628 }
2629 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002630 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002631 }
Evan Chu85b7e842013-01-18 11:02:50 -05002632
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002633 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2634 p_i93->p_update_data = (uint8_t*)GKI_getbuf(RW_I93_FORMAT_DATA_LEN);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002635
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002636 if (!p_i93->p_update_data) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002637 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002638 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002639 break;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002640 }
2641
2642 p = p_i93->p_update_data;
2643
2644 /* Capability Container */
Raphael Collado867d5c32017-03-27 12:49:40 +02002645 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002646 *(p++) = 0x40; /* version 1.0, read/write */
2647
2648 /* if memory size is less than 2048 bytes */
2649 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2650 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2651 8); /* memory size */
2652 else
2653 *(p++) = 0xFF;
2654
2655 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2656 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2657 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2658 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2659 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2660 else
2661 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2662 supported */
2663 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2664 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2665 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2666 supported */
2667 } else if ((p_i93->product_version ==
2668 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2669 (p_i93->product_version ==
2670 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2671 *(p++) = 0;
2672 } else {
2673 /* STM except LRIS2K, Broadcom supports read multi block command */
2674
2675 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2676 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2677 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2678 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2679 *(p++) = 0x00;
2680 else
2681 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2682 }
2683
2684 /* zero length NDEF and Terminator TLV */
2685 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2686 *(p++) = 0x00;
2687 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2688 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2689
2690 /* start from block 0 */
2691 p_i93->rw_offset = 0;
2692
2693 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2694 NFC_STATUS_OK) {
2695 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2696 p_i93->rw_offset += p_i93->block_size;
2697 } else {
2698 rw_i93_handle_error(NFC_STATUS_FAILED);
2699 }
2700 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002701
2702 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2703
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002704 /* if we have more data to write */
2705 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2706 block_number = (p_i93->rw_offset / p_i93->block_size);
2707 p = p_i93->p_update_data + p_i93->rw_offset;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002708
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002709 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2710 NFC_STATUS_OK) {
2711 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2712 p_i93->rw_offset += p_i93->block_size;
2713 } else {
2714 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002715 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002716 } else {
2717 GKI_freebuf(p_i93->p_update_data);
2718 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002719
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002720 p_i93->state = RW_I93_STATE_IDLE;
2721 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002722
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002723 rw_data.status = NFC_STATUS_OK;
2724 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2725 }
2726 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002727
2728 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002729 break;
2730 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002731}
2732
2733/*******************************************************************************
2734**
2735** Function rw_i93_sm_set_read_only
2736**
2737** Description Process read-only procedure
2738**
2739** 1. Update CC as read-only
2740** 2. Lock all block of NDEF TLV
2741** 3. Lock block of CC
2742**
2743** Returns void
2744**
2745*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002746void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2747 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2748 uint8_t flags, block_number;
2749 uint16_t length = p_resp->len;
2750 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2751 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002752
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002753 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2754 "sub_state:%s (0x%x)",
2755 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 -08002756
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002757 STREAM_TO_UINT8(flags, p);
2758 length--;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002759
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002760 if (flags & I93_FLAG_ERROR_DETECTED) {
2761 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2762 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2763 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2764 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2765 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2766 /* ignore error */
2767 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002768 DLOG_IF(INFO, nfc_debug_enabled)
2769 << StringPrintf("Got error flags (0x%02x)", flags);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002770 rw_i93_handle_error(NFC_STATUS_FAILED);
2771 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002772 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002773 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002774
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002775 switch (p_i93->sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002776 case RW_I93_SUBSTATE_WAIT_CC:
2777
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002778 /* mark CC as read-only */
2779 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002780
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002781 if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
2782 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2783 } else {
2784 rw_i93_handle_error(NFC_STATUS_FAILED);
2785 }
2786 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002787
2788 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2789
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002790 /* successfully write CC then lock all blocks of NDEF TLV */
2791 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2792 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002793
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002794 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2795 p_i93->rw_offset += p_i93->block_size;
2796 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2797 } else {
2798 rw_i93_handle_error(NFC_STATUS_FAILED);
2799 }
2800 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002801
2802 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2803
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002804 /* if we need to lock more blocks */
2805 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
2806 /* get the next block of NDEF TLV */
2807 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002808
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002809 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2810 p_i93->rw_offset += p_i93->block_size;
2811 } else {
2812 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002813 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002814 }
2815 /* if the first block of NDEF TLV is different from block of CC */
2816 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
2817 /* lock block of CC */
2818 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
2819 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2820 } else {
2821 rw_i93_handle_error(NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002822 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002823 } else {
2824 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2825 p_i93->state = RW_I93_STATE_IDLE;
2826 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002827
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002828 rw_data.status = NFC_STATUS_OK;
2829 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2830 }
2831 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002832
2833 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2834
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002835 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2836 p_i93->state = RW_I93_STATE_IDLE;
2837 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002838
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002839 rw_data.status = NFC_STATUS_OK;
2840 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2841 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002842
2843 default:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002844 break;
2845 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002846}
2847
2848/*******************************************************************************
2849**
2850** Function rw_i93_handle_error
2851**
2852** Description notify error to application and clean up
2853**
2854** Returns none
2855**
2856*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002857void rw_i93_handle_error(tNFC_STATUS status) {
2858 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2859 tRW_DATA rw_data;
2860 tRW_EVENT event;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002861
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002862 DLOG_IF(INFO, nfc_debug_enabled)
2863 << StringPrintf("status:0x%02X, state:0x%X", status, p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002864
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002865 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002866
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002867 if (rw_cb.p_cback) {
2868 rw_data.status = status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002869
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002870 switch (p_i93->state) {
2871 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2872 event = RW_I93_INTF_ERROR_EVT;
2873 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002874
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002875 case RW_I93_STATE_BUSY:
2876 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
2877 /* There is no response to Stay Quiet command */
2878 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2879 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2880 rw_data.i93_cmd_cmpl.error_code = 0;
2881 event = RW_I93_CMD_CMPL_EVT;
2882 } else {
2883 event = RW_I93_INTF_ERROR_EVT;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002884 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002885 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002886
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002887 case RW_I93_STATE_DETECT_NDEF:
Love Khanna57a3dfa2017-03-28 20:03:38 +05302888 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002889 rw_data.ndef.cur_size = 0;
2890 rw_data.ndef.max_size = 0;
2891 rw_data.ndef.flags = 0;
2892 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2893 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2894 event = RW_I93_NDEF_DETECT_EVT;
2895 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002896
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002897 case RW_I93_STATE_READ_NDEF:
2898 event = RW_I93_NDEF_READ_FAIL_EVT;
2899 break;
2900
2901 case RW_I93_STATE_UPDATE_NDEF:
2902 p_i93->p_update_data = NULL;
2903 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2904 break;
2905
2906 case RW_I93_STATE_FORMAT:
2907 if (p_i93->p_update_data) {
2908 GKI_freebuf(p_i93->p_update_data);
2909 p_i93->p_update_data = NULL;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002910 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002911 event = RW_I93_FORMAT_CPLT_EVT;
2912 break;
2913
2914 case RW_I93_STATE_SET_READ_ONLY:
2915 event = RW_I93_SET_TAG_RO_EVT;
2916 break;
2917
2918 case RW_I93_STATE_PRESENCE_CHECK:
2919 event = RW_I93_PRESENCE_CHECK_EVT;
2920 break;
2921
2922 default:
2923 event = RW_I93_MAX_EVT;
2924 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002925 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002926
2927 p_i93->state = RW_I93_STATE_IDLE;
2928 p_i93->sent_cmd = 0;
2929
2930 if (event != RW_I93_MAX_EVT) {
2931 (*(rw_cb.p_cback))(event, &rw_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002932 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002933 } else {
2934 p_i93->state = RW_I93_STATE_IDLE;
2935 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002936}
2937
2938/*******************************************************************************
2939**
2940** Function rw_i93_process_timeout
2941**
2942** Description process timeout event
2943**
2944** Returns none
2945**
2946*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002947void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2948 NFC_HDR* p_buf;
Evan Chu85b7e842013-01-18 11:02:50 -05002949
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002950 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002951
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002952 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
2953 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
2954 (rw_cb.tcb.i93.p_retry_cmd) &&
2955 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
2956 rw_cb.tcb.i93.retry_count++;
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002957 LOG(ERROR) << StringPrintf("retry_count = %d", rw_cb.tcb.i93.retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05002958
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002959 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2960 rw_cb.tcb.i93.p_retry_cmd = NULL;
Evan Chu7c69b272013-05-14 12:48:36 -04002961
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002962 if (rw_i93_send_to_lower(p_buf)) {
2963 return;
2964 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002965 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002966
2967 /* all retrial is done or failed to send command to lower layer */
2968 if (rw_cb.tcb.i93.p_retry_cmd) {
2969 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
2970 rw_cb.tcb.i93.p_retry_cmd = NULL;
2971 rw_cb.tcb.i93.retry_count = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002972 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002973 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
2974 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002975 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002976 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002977}
2978
2979/*******************************************************************************
2980**
2981** Function rw_i93_data_cback
2982**
2983** Description This callback function receives the data from NFCC.
2984**
2985** Returns none
2986**
2987*******************************************************************************/
Ruchi Kandoi9ba6d242017-10-13 16:07:01 -07002988static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
2989 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002990 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2991 NFC_HDR* p_resp;
2992 tRW_DATA rw_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002993
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08002994 uint8_t begin_state = p_i93->state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002995
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07002996 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002997
Love Khanna57a3dfa2017-03-28 20:03:38 +05302998 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
2999 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003000 nfc_stop_quick_timer(&p_i93->timer);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003001
Jizhou Liao499be102017-08-11 12:57:12 -07003002 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003003 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
3004 p_i93->retry_count++;
Evan Chu85b7e842013-01-18 11:02:50 -05003005
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003006 LOG(ERROR) << StringPrintf("retry_count = %d", p_i93->retry_count);
Evan Chu85b7e842013-01-18 11:02:50 -05003007
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003008 p_resp = p_i93->p_retry_cmd;
3009 p_i93->p_retry_cmd = NULL;
3010 if (rw_i93_send_to_lower(p_resp)) {
3011 return;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003012 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003013 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003014
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003015 /* all retrial is done or failed to send command to lower layer */
3016 if (p_i93->p_retry_cmd) {
3017 GKI_freebuf(p_i93->p_retry_cmd);
Evan Chu85b7e842013-01-18 11:02:50 -05003018 p_i93->p_retry_cmd = NULL;
3019 p_i93->retry_count = 0;
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003020 }
3021
3022 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
3023 } else {
3024 /* free retry buffer */
3025 if (p_i93->p_retry_cmd) {
3026 GKI_freebuf(p_i93->p_retry_cmd);
3027 p_i93->p_retry_cmd = NULL;
3028 p_i93->retry_count = 0;
3029 }
3030 NFC_SetStaticRfCback(NULL);
3031 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
Evan Chu85b7e842013-01-18 11:02:50 -05003032 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003033 return;
3034 }
3035
3036 if (event != NFC_DATA_CEVT) {
3037 return;
3038 }
3039
3040 p_resp = (NFC_HDR*)p_data->data.p_data;
3041
3042 nfc_stop_quick_timer(&p_i93->timer);
3043
3044 /* free retry buffer */
3045 if (p_i93->p_retry_cmd) {
3046 GKI_freebuf(p_i93->p_retry_cmd);
3047 p_i93->p_retry_cmd = NULL;
3048 p_i93->retry_count = 0;
3049 }
Evan Chu85b7e842013-01-18 11:02:50 -05003050
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003051 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
3052 "RW I93 state: <%s (%d)>", rw_i93_get_state_name(p_i93->state).c_str(),
3053 p_i93->state);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003054
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003055 switch (p_i93->state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003056 case RW_I93_STATE_IDLE:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003057 /* Unexpected Response from VICC, it should be raw frame response */
3058 /* forward to upper layer without parsing */
3059 p_i93->sent_cmd = 0;
3060 if (rw_cb.p_cback) {
3061 rw_data.raw_frame.status = p_data->data.status;
3062 rw_data.raw_frame.p_data = p_resp;
3063 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
3064 p_resp = NULL;
3065 } else {
3066 GKI_freebuf(p_resp);
3067 }
3068 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003069 case RW_I93_STATE_BUSY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003070 p_i93->state = RW_I93_STATE_IDLE;
3071 rw_i93_send_to_upper(p_resp);
3072 GKI_freebuf(p_resp);
3073 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003074
3075 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003076 rw_i93_sm_detect_ndef(p_resp);
3077 GKI_freebuf(p_resp);
3078 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003079
3080 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003081 rw_i93_sm_read_ndef(p_resp);
3082 /* p_resp may send upper lyaer */
3083 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003084
3085 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003086 rw_i93_sm_update_ndef(p_resp);
3087 GKI_freebuf(p_resp);
3088 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003089
3090 case RW_I93_STATE_FORMAT:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003091 rw_i93_sm_format(p_resp);
3092 GKI_freebuf(p_resp);
3093 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003094
3095 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003096 rw_i93_sm_set_read_only(p_resp);
3097 GKI_freebuf(p_resp);
3098 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003099
3100 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003101 p_i93->state = RW_I93_STATE_IDLE;
3102 p_i93->sent_cmd = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003103
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003104 /* if any response, send presence check with ok */
3105 rw_data.status = NFC_STATUS_OK;
3106 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3107 GKI_freebuf(p_resp);
3108 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003109
3110 default:
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003111 LOG(ERROR) << StringPrintf("invalid state=%d", p_i93->state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003112 GKI_freebuf(p_resp);
3113 break;
3114 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003115
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003116 if (begin_state != p_i93->state) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003117 DLOG_IF(INFO, nfc_debug_enabled)
3118 << StringPrintf("RW I93 state changed:<%s> -> <%s>",
3119 rw_i93_get_state_name(begin_state).c_str(),
3120 rw_i93_get_state_name(p_i93->state).c_str());
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003121 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003122}
3123
3124/*******************************************************************************
3125**
3126** Function rw_i93_select
3127**
Love Khanna57a3dfa2017-03-28 20:03:38 +05303128** Description Initialise ISO 15693 / T5T RW
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003129**
3130** Returns NFC_STATUS_OK if success
3131**
3132*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003133tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
3134 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3135 uint8_t uid[I93_UID_BYTE_LEN], *p;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003136
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003137 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003138
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003139 NFC_SetStaticRfCback(rw_i93_data_cback);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003140
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003141 p_i93->state = RW_I93_STATE_IDLE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003142
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003143 /* convert UID to big endian format - MSB(0xE0) in first byte */
3144 p = uid;
3145 STREAM_TO_ARRAY8(p, p_uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003146
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003147 rw_i93_get_product_version(uid);
Evan Chu85b7e842013-01-18 11:02:50 -05003148
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003149 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003150}
3151
3152/*******************************************************************************
3153**
3154** Function RW_I93Inventory
3155**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07003156** Description This function send Inventory command with/without AFI
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003157** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3158**
3159** RW_I93_RESPONSE_EVT will be returned
3160**
3161** Returns NFC_STATUS_OK if success
3162** NFC_STATUS_NO_BUFFERS if out of buffer
3163** NFC_STATUS_BUSY if busy
3164** NFC_STATUS_FAILED if other error
3165**
3166*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003167tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3168 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003169
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003170 DLOG_IF(INFO, nfc_debug_enabled)
3171 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003172
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003173 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003174 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3175 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003176 return NFC_STATUS_BUSY;
3177 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003178
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003179 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003180
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003181 if (status == NFC_STATUS_OK) {
3182 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3183 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003184
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003185 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003186}
3187
3188/*******************************************************************************
3189**
3190** Function RW_I93StayQuiet
3191**
3192** Description This function send Inventory command
3193**
3194** RW_I93_CMD_CMPL_EVT will be returned
3195**
3196** Returns NFC_STATUS_OK if success
3197** NFC_STATUS_NO_BUFFERS if out of buffer
3198** NFC_STATUS_BUSY if busy
3199** NFC_STATUS_FAILED if other error
3200**
3201*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003202tNFC_STATUS RW_I93StayQuiet(void) {
3203 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003204
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003205 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003206
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003207 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003208 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3209 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003210 return NFC_STATUS_BUSY;
3211 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003212
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003213 status = rw_i93_send_cmd_stay_quiet();
3214 if (status == NFC_STATUS_OK) {
3215 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3216 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003217
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003218 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003219}
3220
3221/*******************************************************************************
3222**
3223** Function RW_I93ReadSingleBlock
3224**
3225** Description This function send Read Single Block command
3226**
3227** RW_I93_RESPONSE_EVT will be returned
3228**
3229** Returns NFC_STATUS_OK if success
3230** NFC_STATUS_NO_BUFFERS if out of buffer
3231** NFC_STATUS_BUSY if busy
3232** NFC_STATUS_FAILED if other error
3233**
3234*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003235tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3236 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003237
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003238 DLOG_IF(INFO, nfc_debug_enabled)
3239 << StringPrintf("block_number:0x%02X", block_number);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003240
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003241 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003242 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3243 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003244 return NFC_STATUS_BUSY;
3245 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003246
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003247 status = rw_i93_send_cmd_read_single_block(block_number, false);
3248 if (status == NFC_STATUS_OK) {
3249 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3250 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003251
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003252 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003253}
3254
3255/*******************************************************************************
3256**
3257** Function RW_I93WriteSingleBlock
3258**
3259** Description This function send Write Single Block command
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003260** Application must get block size first by calling
3261** RW_I93GetSysInfo().
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003262**
3263** RW_I93_CMD_CMPL_EVT will be returned
3264**
3265** Returns NFC_STATUS_OK if success
3266** NFC_STATUS_NO_BUFFERS if out of buffer
3267** NFC_STATUS_BUSY if busy
3268** NFC_STATUS_FAILED if other error
3269**
3270*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003271tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3272 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003273
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003274 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003275
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003276 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003277 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3278 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003279 return NFC_STATUS_BUSY;
3280 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003281
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003282 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003283 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003284 return NFC_STATUS_FAILED;
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_write_single_block(block_number, p_data);
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_I93LockBlock
3298**
3299** Description This function send Lock Block command
3300**
3301** RW_I93_CMD_CMPL_EVT will be returned
3302**
3303** Returns NFC_STATUS_OK if success
3304** NFC_STATUS_NO_BUFFERS if out of buffer
3305** NFC_STATUS_BUSY if busy
3306** NFC_STATUS_FAILED if other error
3307**
3308*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003309tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3310 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003311
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003312 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003313
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003314 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003315 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3316 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003317 return NFC_STATUS_BUSY;
3318 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003319
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003320 status = rw_i93_send_cmd_lock_block(block_number);
3321 if (status == NFC_STATUS_OK) {
3322 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3323 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003324
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003325 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003326}
3327
3328/*******************************************************************************
3329**
3330** Function RW_I93ReadMultipleBlocks
3331**
3332** Description This function send Read Multiple Blocks command
3333**
3334** RW_I93_RESPONSE_EVT will be returned
3335**
3336** Returns NFC_STATUS_OK if success
3337** NFC_STATUS_NO_BUFFERS if out of buffer
3338** NFC_STATUS_BUSY if busy
3339** NFC_STATUS_FAILED if other error
3340**
3341*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003342tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3343 uint16_t number_blocks) {
3344 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003345
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003346 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003347
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003348 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003349 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3350 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003351 return NFC_STATUS_BUSY;
3352 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003353
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003354 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3355 if (status == NFC_STATUS_OK) {
3356 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3357 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003358
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003359 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003360}
3361
3362/*******************************************************************************
3363**
3364** Function RW_I93WriteMultipleBlocks
3365**
3366** Description This function send Write Multiple Blocks command
3367**
3368** RW_I93_CMD_CMPL_EVT will be returned
3369**
3370** Returns NFC_STATUS_OK if success
3371** NFC_STATUS_NO_BUFFERS if out of buffer
3372** NFC_STATUS_BUSY if busy
3373** NFC_STATUS_FAILED if other error
3374**
3375*******************************************************************************/
Raphael Collado867d5c32017-03-27 12:49:40 +02003376tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003377 uint16_t number_blocks, uint8_t* p_data) {
3378 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003379
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003380 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003381
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003382 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003383 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3384 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003385 return NFC_STATUS_BUSY;
3386 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003387
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003388 if (rw_cb.tcb.i93.block_size == 0) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003389 LOG(ERROR) << StringPrintf("Block size is unknown");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003390 return NFC_STATUS_FAILED;
3391 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003392
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003393 status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
3394 p_data);
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_I93Select
3405**
3406** Description This function send Select command
3407**
3408** UID[0]: 0xE0, MSB
3409** UID[1]: IC Mfg Code
3410** ...
3411** UID[7]: LSB
3412**
3413** RW_I93_CMD_CMPL_EVT will be returned
3414**
3415** Returns NFC_STATUS_OK if success
3416** NFC_STATUS_NO_BUFFERS if out of buffer
3417** NFC_STATUS_BUSY if busy
3418** NFC_STATUS_FAILED if other error
3419**
3420*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003421tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3422 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003423
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003424 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003425
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003426 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003427 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3428 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003429 return NFC_STATUS_BUSY;
3430 }
3431
3432 if (p_uid) {
3433 status = rw_i93_send_cmd_select(p_uid);
3434 if (status == NFC_STATUS_OK) {
3435 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003436 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003437 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003438 LOG(ERROR) << StringPrintf("UID shall be provided");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003439 status = NFC_STATUS_FAILED;
3440 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003441
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003442 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003443}
3444
3445/*******************************************************************************
3446**
3447** Function RW_I93ResetToReady
3448**
3449** Description This function send Reset To Ready command
3450**
3451** RW_I93_CMD_CMPL_EVT will be returned
3452**
3453** Returns NFC_STATUS_OK if success
3454** NFC_STATUS_NO_BUFFERS if out of buffer
3455** NFC_STATUS_BUSY if busy
3456** NFC_STATUS_FAILED if other error
3457**
3458*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003459tNFC_STATUS RW_I93ResetToReady(void) {
3460 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003461
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003462 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003463
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003464 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003465 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3466 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003467 return NFC_STATUS_BUSY;
3468 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003469
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003470 status = rw_i93_send_cmd_reset_to_ready();
3471 if (status == NFC_STATUS_OK) {
3472 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3473 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003474
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003475 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003476}
3477
3478/*******************************************************************************
3479**
3480** Function RW_I93WriteAFI
3481**
3482** Description This function send Write AFI command
3483**
3484** RW_I93_CMD_CMPL_EVT will be returned
3485**
3486** Returns NFC_STATUS_OK if success
3487** NFC_STATUS_NO_BUFFERS if out of buffer
3488** NFC_STATUS_BUSY if busy
3489** NFC_STATUS_FAILED if other error
3490**
3491*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003492tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3493 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003494
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003495 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003496
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003497 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003498 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3499 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003500 return NFC_STATUS_BUSY;
3501 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003502
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003503 status = rw_i93_send_cmd_write_afi(afi);
3504 if (status == NFC_STATUS_OK) {
3505 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3506 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003507
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003508 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003509}
3510
3511/*******************************************************************************
3512**
3513** Function RW_I93LockAFI
3514**
3515** Description This function send Lock AFI command
3516**
3517** RW_I93_CMD_CMPL_EVT will be returned
3518**
3519** Returns NFC_STATUS_OK if success
3520** NFC_STATUS_NO_BUFFERS if out of buffer
3521** NFC_STATUS_BUSY if busy
3522** NFC_STATUS_FAILED if other error
3523**
3524*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003525tNFC_STATUS RW_I93LockAFI(void) {
3526 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003527
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003528 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003529
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003530 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003531 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3532 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003533 return NFC_STATUS_BUSY;
3534 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003535
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003536 status = rw_i93_send_cmd_lock_afi();
3537 if (status == NFC_STATUS_OK) {
3538 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3539 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003540
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003541 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003542}
3543
3544/*******************************************************************************
3545**
3546** Function RW_I93WriteDSFID
3547**
3548** Description This function send Write DSFID command
3549**
3550** RW_I93_CMD_CMPL_EVT will be returned
3551**
3552** Returns NFC_STATUS_OK if success
3553** NFC_STATUS_NO_BUFFERS if out of buffer
3554** NFC_STATUS_BUSY if busy
3555** NFC_STATUS_FAILED if other error
3556**
3557*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003558tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3559 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003560
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003561 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003562
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003563 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003564 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3565 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003566 return NFC_STATUS_BUSY;
3567 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003568
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003569 status = rw_i93_send_cmd_write_dsfid(dsfid);
3570 if (status == NFC_STATUS_OK) {
3571 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3572 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003573
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003574 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003575}
3576
3577/*******************************************************************************
3578**
3579** Function RW_I93LockDSFID
3580**
3581** Description This function send Lock DSFID command
3582**
3583** RW_I93_CMD_CMPL_EVT will be returned
3584**
3585** Returns NFC_STATUS_OK if success
3586** NFC_STATUS_NO_BUFFERS if out of buffer
3587** NFC_STATUS_BUSY if busy
3588** NFC_STATUS_FAILED if other error
3589**
3590*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003591tNFC_STATUS RW_I93LockDSFID(void) {
3592 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003593
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003594 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003595
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003596 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003597 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3598 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003599 return NFC_STATUS_BUSY;
3600 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003601
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003602 status = rw_i93_send_cmd_lock_dsfid();
3603 if (status == NFC_STATUS_OK) {
3604 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3605 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003606
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003607 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003608}
3609
3610/*******************************************************************************
3611**
3612** Function RW_I93GetSysInfo
3613**
3614** Description This function send Get System Information command
3615**
3616** RW_I93_RESPONSE_EVT will be returned
3617**
3618** Returns NFC_STATUS_OK if success
3619** NFC_STATUS_NO_BUFFERS if out of buffer
3620** NFC_STATUS_BUSY if busy
3621** NFC_STATUS_FAILED if other error
3622**
3623*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003624tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3625 tNFC_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003626
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003627 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003628
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003629 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003630 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3631 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003632 return NFC_STATUS_BUSY;
3633 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003634
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003635 if (p_uid) {
3636 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3637 } else {
3638 status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
3639 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003640
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003641 if (status == NFC_STATUS_OK) {
3642 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3643 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003644
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003645 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003646}
3647
3648/*******************************************************************************
3649**
3650** Function RW_I93GetMultiBlockSecurityStatus
3651**
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003652** Description This function send Get Multiple Block Security Status
3653** command
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003654**
3655** RW_I93_RESPONSE_EVT will be returned
3656**
3657** Returns NFC_STATUS_OK if success
3658** NFC_STATUS_NO_BUFFERS if out of buffer
3659** NFC_STATUS_BUSY if busy
3660** NFC_STATUS_FAILED if other error
3661**
3662*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003663tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3664 uint16_t number_blocks) {
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(
3671 "Unable to start command at state "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003672 "(0x%X)",
3673 rw_cb.tcb.i93.state);
3674 return NFC_STATUS_BUSY;
3675 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003676
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003677 status =
3678 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3679 if (status == NFC_STATUS_OK) {
3680 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3681 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003682
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003683 return status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003684}
3685
3686/*******************************************************************************
3687**
3688** Function RW_I93DetectNDef
3689**
3690** Description This function performs NDEF detection procedure
3691**
3692** RW_I93_NDEF_DETECT_EVT will be returned
3693**
3694** Returns NFC_STATUS_OK if success
3695** NFC_STATUS_FAILED if busy or other error
3696**
3697*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003698tNFC_STATUS RW_I93DetectNDef(void) {
3699 tNFC_STATUS status;
3700 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003701
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003702 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003703
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003704 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003705 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3706 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003707 return NFC_STATUS_FAILED;
3708 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003709
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003710 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
3711 status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
3712 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3713 } else if ((rw_cb.tcb.i93.num_block == 0) ||
3714 (rw_cb.tcb.i93.block_size == 0)) {
3715 status =
3716 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3717 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
Evan Chu85b7e842013-01-18 11:02:50 -05003718
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003719 /* clear all flags */
3720 rw_cb.tcb.i93.intl_flags = 0;
3721 } else {
3722 /* read CC in the first block */
3723 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3724 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3725 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003726
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003727 if (status == NFC_STATUS_OK) {
3728 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3729 rw_cb.tcb.i93.sub_state = sub_state;
Evan Chu85b7e842013-01-18 11:02:50 -05003730
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003731 /* clear flags except flag for 2 bytes of number of blocks */
3732 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3733 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003734
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003735 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003736}
3737
3738/*******************************************************************************
3739**
3740** Function RW_I93ReadNDef
3741**
3742** Description This function performs NDEF read procedure
3743** Note: RW_I93DetectNDef () must be called before using this
3744**
3745** The following event will be returned
3746** RW_I93_NDEF_READ_EVT for each segmented NDEF message
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003747** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3748** complete NDEF
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003749** RW_I93_NDEF_READ_FAIL_EVT for failure
3750**
3751** Returns NFC_STATUS_OK if success
3752** NFC_STATUS_FAILED if I93 is busy or other error
3753**
3754*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003755tNFC_STATUS RW_I93ReadNDef(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003756 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003757
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003758 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003759 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3760 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003761 return NFC_STATUS_FAILED;
3762 }
3763
3764 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
3765 (rw_cb.tcb.i93.ndef_length > 0)) {
3766 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3767 rw_cb.tcb.i93.rw_length = 0;
3768
3769 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
3770 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3771 } else {
3772 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003773 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003774 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003775 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003776 return NFC_STATUS_FAILED;
3777 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003778
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003779 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003780}
3781
3782/*******************************************************************************
3783**
3784** Function RW_I93UpdateNDef
3785**
3786** Description This function performs NDEF update procedure
3787** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003788** Updating data must not be removed until returning
3789** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003790**
3791** The following event will be returned
3792** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3793** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3794**
3795** Returns NFC_STATUS_OK if success
3796** NFC_STATUS_FAILED if I93 is busy or other error
3797**
3798*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003799tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3800 uint16_t block_number;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003801
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003802 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003803
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003804 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003805 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3806 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003807 return NFC_STATUS_FAILED;
3808 }
3809
3810 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3811 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003812 LOG(ERROR) << StringPrintf("NDEF is read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003813 return NFC_STATUS_FAILED;
3814 }
3815 if (rw_cb.tcb.i93.max_ndef_length < length) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003816 LOG(ERROR) << StringPrintf(
3817 "data (%d bytes) is more than max NDEF length "
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003818 "(%d)",
3819 length, rw_cb.tcb.i93.max_ndef_length);
3820 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003821 }
3822
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003823 rw_cb.tcb.i93.ndef_length = length;
3824 rw_cb.tcb.i93.p_update_data = p_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003825
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003826 /* read length field */
3827 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3828 rw_cb.tcb.i93.rw_length = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003829
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003830 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003831
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003832 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
3833 NFC_STATUS_OK) {
3834 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3835 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3836 } else {
3837 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003838 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003839 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003840 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003841 return NFC_STATUS_FAILED;
3842 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003843
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003844 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003845}
3846
3847/*******************************************************************************
3848**
3849** Function RW_I93FormatNDef
3850**
3851** Description This function performs formatting procedure
3852**
3853** RW_I93_FORMAT_CPLT_EVT will be returned
3854**
3855** Returns NFC_STATUS_OK if success
3856** NFC_STATUS_FAILED if busy or other error
3857**
3858*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003859tNFC_STATUS RW_I93FormatNDef(void) {
3860 tNFC_STATUS status;
3861 tRW_I93_RW_SUBSTATE sub_state;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003862
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003863 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003864
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003865 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003866 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3867 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003868 return NFC_STATUS_FAILED;
3869 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003870
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003871 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
3872 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
3873 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
3874 */
3875 rw_cb.tcb.i93.rw_offset = 0;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003876
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003877 /* read blocks with option flag to get block security status */
3878 status = rw_i93_send_cmd_read_single_block(0x0000, true);
3879 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
3880 } else {
3881 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3882 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3883 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003884
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003885 if (status == NFC_STATUS_OK) {
3886 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
3887 rw_cb.tcb.i93.sub_state = sub_state;
3888 rw_cb.tcb.i93.intl_flags = 0;
3889 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003890
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003891 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003892}
3893
3894/*******************************************************************************
3895**
3896** Function RW_I93SetTagReadOnly
3897**
3898** Description This function performs NDEF read-only procedure
3899** Note: RW_I93DetectNDef () must be called before using this
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003900** Updating data must not be removed until returning
3901** event
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003902**
3903** The RW_I93_SET_TAG_RO_EVT event will be returned.
3904**
3905** Returns NFC_STATUS_OK if success
3906** NFC_STATUS_FAILED if I93 is busy or other error
3907**
3908*******************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003909tNFC_STATUS RW_I93SetTagReadOnly(void) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003910 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003911
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003912 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003913 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3914 rw_cb.tcb.i93.state);
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003915 return NFC_STATUS_FAILED;
3916 }
3917
3918 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3919 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003920 LOG(ERROR) << StringPrintf("NDEF is already read-only");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003921 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003922 }
3923
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003924 /* get CC in the first block */
3925 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
3926 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
3927 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
3928 } else {
3929 return NFC_STATUS_FAILED;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003930 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003931 } else {
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003932 LOG(ERROR) << StringPrintf("No NDEF detected");
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003933 return NFC_STATUS_FAILED;
3934 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003935
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003936 return NFC_STATUS_OK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003937}
3938
3939/*****************************************************************************
3940**
3941** Function RW_I93PresenceCheck
3942**
3943** Description Check if the tag is still in the field.
3944**
3945** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
3946** presence or non-presence.
3947**
3948** Returns NFC_STATUS_OK, if raw data frame sent
Ruchi Kandoi552f2b72017-01-28 16:22:55 -08003949** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3950** operation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003951** NFC_STATUS_FAILED: other error
3952**
3953*****************************************************************************/
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003954tNFC_STATUS RW_I93PresenceCheck(void) {
3955 tNFC_STATUS status;
3956 tRW_DATA evt_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003957
Ruchi Kandoi6767aec2017-09-26 09:46:26 -07003958 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003959
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003960 if (!rw_cb.p_cback) {
3961 return NFC_STATUS_FAILED;
3962 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
3963 evt_data.status = NFC_STATUS_FAILED;
3964 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003965
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003966 return NFC_STATUS_OK;
3967 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3968 return NFC_STATUS_BUSY;
3969 } else {
3970 /* The support of AFI by the VICC is optional, so do not include AFI */
3971 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3972
3973 if (status == NFC_STATUS_OK) {
3974 /* do not retry during presence check */
3975 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
3976 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003977 }
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003978 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003979
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003980 return (status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003981}
3982
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003983/*******************************************************************************
3984**
3985** Function rw_i93_get_state_name
3986**
3987** Description This function returns the state name.
3988**
3989** NOTE conditionally compiled to save memory.
3990**
3991** Returns pointer to the name
3992**
3993*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003994static std::string rw_i93_get_state_name(uint8_t state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08003995 switch (state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003996 case RW_I93_STATE_NOT_ACTIVATED:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003997 return "NOT_ACTIVATED";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08003998 case RW_I93_STATE_IDLE:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07003999 return "IDLE";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004000 case RW_I93_STATE_BUSY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004001 return "BUSY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004002 case RW_I93_STATE_DETECT_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004003 return "NDEF_DETECTION";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004004 case RW_I93_STATE_READ_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004005 return "READ_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004006 case RW_I93_STATE_UPDATE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004007 return "UPDATE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004008 case RW_I93_STATE_FORMAT:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004009 return "FORMAT";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004010 case RW_I93_STATE_SET_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004011 return "SET_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004012 case RW_I93_STATE_PRESENCE_CHECK:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004013 return "PRESENCE_CHECK";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004014 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004015 return "???? UNKNOWN STATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004016 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004017}
4018
4019/*******************************************************************************
4020**
4021** Function rw_i93_get_sub_state_name
4022**
4023** Description This function returns the sub_state name.
4024**
4025** NOTE conditionally compiled to save memory.
4026**
4027** Returns pointer to the name
4028**
4029*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004030static std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004031 switch (sub_state) {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004032 case RW_I93_SUBSTATE_WAIT_UID:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004033 return "WAIT_UID";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004034 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004035 return "WAIT_SYS_INFO";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004036 case RW_I93_SUBSTATE_WAIT_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004037 return "WAIT_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004038 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004039 return "SEARCH_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004040 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004041 return "CHECK_LOCK_STATUS";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004042 case RW_I93_SUBSTATE_RESET_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004043 return "RESET_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004044 case RW_I93_SUBSTATE_WRITE_NDEF:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004045 return "WRITE_NDEF";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004046 case RW_I93_SUBSTATE_UPDATE_LEN:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004047 return "UPDATE_LEN";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004048 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004049 return "WAIT_RESET_DSFID_AFI";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004050 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004051 return "CHECK_READ_ONLY";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004052 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004053 return "WRITE_CC_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004054 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004055 return "WAIT_UPDATE_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004056 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004057 return "LOCK_NDEF_TLV";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004058 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004059 return "WAIT_LOCK_CC";
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004060 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004061 return "???? UNKNOWN SUBSTATE";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004062 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004063}
Evan Chu85b7e842013-01-18 11:02:50 -05004064
4065/*******************************************************************************
4066**
4067** Function rw_i93_get_tag_name
4068**
4069** Description This function returns the tag name.
4070**
4071** NOTE conditionally compiled to save memory.
4072**
4073** Returns pointer to the name
4074**
4075*******************************************************************************/
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004076static std::string rw_i93_get_tag_name(uint8_t product_version) {
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004077 switch (product_version) {
Evan Chu85b7e842013-01-18 11:02:50 -05004078 case RW_I93_ICODE_SLI:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004079 return "SLI/SLIX";
Evan Chu85b7e842013-01-18 11:02:50 -05004080 case RW_I93_ICODE_SLI_S:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004081 return "SLI-S/SLIX-S";
Evan Chu85b7e842013-01-18 11:02:50 -05004082 case RW_I93_ICODE_SLI_L:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004083 return "SLI-L/SLIX-L";
Evan Chu85b7e842013-01-18 11:02:50 -05004084 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004085 return "Tag-it HF-I Plus Inlay";
Evan Chu85b7e842013-01-18 11:02:50 -05004086 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004087 return "Tag-it HF-I Plus Chip";
Evan Chu85b7e842013-01-18 11:02:50 -05004088 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004089 return "Tag-it HF-I Standard Chip/Inlyas";
Evan Chu85b7e842013-01-18 11:02:50 -05004090 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004091 return "Tag-it HF-I Pro Chip/Inlays";
Evan Chu85b7e842013-01-18 11:02:50 -05004092 case RW_I93_STM_LRI1K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004093 return "LRi1K";
Evan Chu85b7e842013-01-18 11:02:50 -05004094 case RW_I93_STM_LRI2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004095 return "LRi2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004096 case RW_I93_STM_LRIS2K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004097 return "LRiS2K";
Evan Chu85b7e842013-01-18 11:02:50 -05004098 case RW_I93_STM_LRIS64K:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004099 return "LRiS64K";
Evan Chu85b7e842013-01-18 11:02:50 -05004100 case RW_I93_STM_M24LR64_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004101 return "M24LR64";
Evan Chu85b7e842013-01-18 11:02:50 -05004102 case RW_I93_STM_M24LR04E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004103 return "M24LR04E";
Evan Chu85b7e842013-01-18 11:02:50 -05004104 case RW_I93_STM_M24LR16E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004105 return "M24LR16E";
Evan Chu85b7e842013-01-18 11:02:50 -05004106 case RW_I93_STM_M24LR64E_R:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004107 return "M24LR64E";
Raphael Collado867d5c32017-03-27 12:49:40 +02004108 case RW_I93_STM_ST25DV04K:
4109 return "ST25DV04";
4110 case RW_I93_STM_ST25DVHIK:
4111 return "ST25DV";
Evan Chu85b7e842013-01-18 11:02:50 -05004112 case RW_I93_UNKNOWN_PRODUCT:
4113 default:
Ruchi Kandoi7dab0e52017-08-03 13:09:49 -07004114 return "UNKNOWN";
Ruchi Kandoi6fca02d2017-01-30 14:28:16 -08004115 }
Evan Chu85b7e842013-01-18 11:02:50 -05004116}