blob: 42a9c1ca5619e5af0ec6250b58cfc346a845ac56 [file] [log] [blame]
nxpandroidc7611652015-09-23 16:42:05 +05301/******************************************************************************
2 *
3 * Copyright (C) 2011-2014 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
nxpandroidc7611652015-09-23 16:42:05 +053018
19/******************************************************************************
20 *
21 * This file contains the implementation for ISO 15693 in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
nxpandroidc7611652015-09-23 16:42:05 +053026
nxf24591c1cbeab2018-02-21 17:32:26 +053027#include <android-base/stringprintf.h>
28#include <base/logging.h>
29
30#include "nfc_target.h"
31
32#include "bt_types.h"
nxpandroidc7611652015-09-23 16:42:05 +053033#include "nfc_api.h"
34#include "nfc_int.h"
35#include "rw_api.h"
36#include "rw_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053037#include "trace_api.h"
nxpandroidc7611652015-09-23 16:42:05 +053038
nxf24591c1cbeab2018-02-21 17:32:26 +053039using android::base::StringPrintf;
40
41extern bool nfc_debug_enabled;
42
nxpandroid8f6d0532017-07-12 18:25:30 +053043/* Response timeout */
nxpandroid8f6d0532017-07-12 18:25:30 +053044#define RW_I93_TOUT_RESP 1000
nxpandroid8f6d0532017-07-12 18:25:30 +053045/* stay quiet timeout */
46#define RW_I93_TOUT_STAY_QUIET 200
47/* max reading data if read multi block is supported */
48#define RW_I93_READ_MULTI_BLOCK_SIZE 128
49/* CC, zero length NDEF, Terminator TLV */
50#define RW_I93_FORMAT_DATA_LEN 8
51/* max getting lock status if get multi block sec is supported */
52#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
nxpandroidc7611652015-09-23 16:42:05 +053053
54/* main state */
nxpandroid8f6d0532017-07-12 18:25:30 +053055enum {
56 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
57 RW_I93_STATE_IDLE, /* waiting for upper layer API */
58 RW_I93_STATE_BUSY, /* waiting for response from tag */
nxpandroidc7611652015-09-23 16:42:05 +053059
nxpandroid8f6d0532017-07-12 18:25:30 +053060 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
61 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
62 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
63 RW_I93_STATE_FORMAT, /* performing format procedure */
64 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
nxpandroidc7611652015-09-23 16:42:05 +053065
nxpandroid8f6d0532017-07-12 18:25:30 +053066 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
nxpandroidc7611652015-09-23 16:42:05 +053067};
68
69/* sub state */
nxpandroid8f6d0532017-07-12 18:25:30 +053070enum {
71 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
72 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
73 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
74 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
75 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
nxpandroidc7611652015-09-23 16:42:05 +053076
nxpandroid8f6d0532017-07-12 18:25:30 +053077 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
78 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
79 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
nxpandroidc7611652015-09-23 16:42:05 +053080
nxpandroid8f6d0532017-07-12 18:25:30 +053081 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
82 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
83 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
84 */
nxpandroidc7611652015-09-23 16:42:05 +053085
nxpandroid8f6d0532017-07-12 18:25:30 +053086 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
87 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
88 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
nxpandroidc7611652015-09-23 16:42:05 +053089};
90
nxf24591c1cbeab2018-02-21 17:32:26 +053091static std::string rw_i93_get_state_name(uint8_t state);
92static std::string rw_i93_get_sub_state_name(uint8_t sub_state);
93static std::string rw_i93_get_tag_name(uint8_t product_version);
nxpandroidc7611652015-09-23 16:42:05 +053094
nxpandroid8f6d0532017-07-12 18:25:30 +053095static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
96 tNFC_CONN* p_data);
97void rw_i93_handle_error(tNFC_STATUS status);
98tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
nxf24591c1cbeab2018-02-21 17:32:26 +053099tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
nxpandroidc7611652015-09-23 16:42:05 +0530100
101/*******************************************************************************
102**
103** Function rw_i93_get_product_version
104**
105** Description Get product version from UID
106**
107** Returns void
108**
109*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530110void rw_i93_get_product_version(uint8_t* p_uid) {
111 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
nxpandroidc7611652015-09-23 16:42:05 +0530112
nxpandroid8f6d0532017-07-12 18:25:30 +0530113 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
114 return;
115 }
nxpandroidc7611652015-09-23 16:42:05 +0530116
nxf24591c1cbeab2018-02-21 17:32:26 +0530117 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530118
nxpandroid8f6d0532017-07-12 18:25:30 +0530119 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530120
nxpandroid8f6d0532017-07-12 18:25:30 +0530121 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
122 if (p_uid[2] == I93_UID_ICODE_SLI)
123 p_i93->product_version = RW_I93_ICODE_SLI;
124 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
125 p_i93->product_version = RW_I93_ICODE_SLI_S;
126 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
127 p_i93->product_version = RW_I93_ICODE_SLI_L;
nxpandroidc7611652015-09-23 16:42:05 +0530128 else
nxpandroid8f6d0532017-07-12 18:25:30 +0530129 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
130 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
131 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
132 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
133 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
134 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
135 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
136 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
137 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
138 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
139 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
140 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
141 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
142 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
143 else
144 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
145 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
146 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
147 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
148 p_i93->product_version = RW_I93_STM_M24LR04E_R;
149 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
150 p_i93->product_version = RW_I93_STM_M24LR16E_R;
151 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
152 p_i93->product_version = RW_I93_STM_M24LR64E_R;
nxf24591c1cbeab2018-02-21 17:32:26 +0530153 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DVHIK)
154 p_i93->product_version = RW_I93_STM_ST25DVHIK;
155 else if (p_i93->ic_reference == I93_IC_REF_STM_ST25DV04K)
156 p_i93->product_version = RW_I93_STM_ST25DV04K;
nxpandroid8f6d0532017-07-12 18:25:30 +0530157 else {
158 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
159 case I93_IC_REF_STM_LRI1K:
160 p_i93->product_version = RW_I93_STM_LRI1K;
161 break;
162 case I93_IC_REF_STM_LRI2K:
163 p_i93->product_version = RW_I93_STM_LRI2K;
164 break;
165 case I93_IC_REF_STM_LRIS2K:
166 p_i93->product_version = RW_I93_STM_LRIS2K;
167 break;
168 case I93_IC_REF_STM_LRIS64K:
169 p_i93->product_version = RW_I93_STM_LRIS64K;
170 break;
171 case I93_IC_REF_STM_M24LR64_R:
172 p_i93->product_version = RW_I93_STM_M24LR64_R;
173 break;
174 default:
175 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
176 break;
177 }
nxpandroidc7611652015-09-23 16:42:05 +0530178 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530179 } else {
180 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
181 }
nxpandroidc7611652015-09-23 16:42:05 +0530182
nxf24591c1cbeab2018-02-21 17:32:26 +0530183 DLOG_IF(INFO, nfc_debug_enabled)
184 << StringPrintf("product_version = <%s>",
185 rw_i93_get_tag_name(p_i93->product_version).c_str());
nxpandroidc7611652015-09-23 16:42:05 +0530186
nxpandroid8f6d0532017-07-12 18:25:30 +0530187 switch (p_i93->product_version) {
nxpandroidc7611652015-09-23 16:42:05 +0530188 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
189 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
nxpandroid8f6d0532017-07-12 18:25:30 +0530190 /* these don't support Get System Information Command */
191 /* these support only Inventory, Stay Quiet, Read Single Block, Write
192 * Single Block, Lock Block */
193 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
194 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
195 break;
nxpandroidc7611652015-09-23 16:42:05 +0530196 default:
nxpandroid8f6d0532017-07-12 18:25:30 +0530197 break;
198 }
nxpandroidc7611652015-09-23 16:42:05 +0530199}
200
201/*******************************************************************************
202**
nxf24591c1cbeab2018-02-21 17:32:26 +0530203** Function rw_i93_process_ext_sys_info
204**
205** Description Store extended system information of tag
206**
207** Returns FALSE if retrying with protocol extension flag
208**
209*******************************************************************************/
210bool rw_i93_process_ext_sys_info(uint8_t* p_data) {
211 uint8_t* p = p_data;
212 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
213 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
214
215 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
216
217 STREAM_TO_UINT8(p_i93->info_flags, p);
218
219 p_uid = uid;
220 STREAM_TO_ARRAY8(p_uid, p);
221
222 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
223 STREAM_TO_UINT8(p_i93->dsfid, p);
224 }
225 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
226 STREAM_TO_UINT8(p_i93->afi, p);
227 }
228 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
229 STREAM_TO_UINT16(p_i93->num_block, p);
230
231 /* it is one less than actual number of bytes */
232 p_i93->num_block += 1;
233
234 STREAM_TO_UINT8(p_i93->block_size, p);
235 /* it is one less than actual number of blocks */
236 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
237 }
238 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
239 STREAM_TO_UINT8(p_i93->ic_reference, p);
240
241 /* clear existing UID to set product version */
242 p_i93->uid[0] = 0x00;
243
244 /* store UID and get product version */
245 rw_i93_get_product_version(p_uid);
246
247 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
248 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
249 /* STM supports more than 2040 bytes */
250 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
251 }
252 }
253 }
254 return true;
255}
256
257/*******************************************************************************
258**
nxpandroidc7611652015-09-23 16:42:05 +0530259** Function rw_i93_process_sys_info
260**
261** Description Store system information of tag
262**
nxf24591c1cbeab2018-02-21 17:32:26 +0530263** Returns FALSE if retrying with protocol extension flag
nxpandroidc7611652015-09-23 16:42:05 +0530264**
265*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530266bool rw_i93_process_sys_info(uint8_t* p_data) {
267 uint8_t* p = p_data;
268 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
269 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
nxpandroidc7611652015-09-23 16:42:05 +0530270
nxf24591c1cbeab2018-02-21 17:32:26 +0530271 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530272
nxpandroid8f6d0532017-07-12 18:25:30 +0530273 STREAM_TO_UINT8(p_i93->info_flags, p);
nxpandroidc7611652015-09-23 16:42:05 +0530274
nxpandroid8f6d0532017-07-12 18:25:30 +0530275 p_uid = uid;
276 STREAM_TO_ARRAY8(p_uid, p);
nxpandroidc7611652015-09-23 16:42:05 +0530277
nxpandroid8f6d0532017-07-12 18:25:30 +0530278 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
279 STREAM_TO_UINT8(p_i93->dsfid, p);
280 }
281 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
282 STREAM_TO_UINT8(p_i93->afi, p);
283 }
284 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
285 if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
286 STREAM_TO_UINT16(p_i93->num_block, p);
287 } else {
288 STREAM_TO_UINT8(p_i93->num_block, p);
nxpandroidc7611652015-09-23 16:42:05 +0530289 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530290 /* it is one less than actual number of bytes */
291 p_i93->num_block += 1;
nxpandroidc7611652015-09-23 16:42:05 +0530292
nxpandroid8f6d0532017-07-12 18:25:30 +0530293 STREAM_TO_UINT8(p_i93->block_size, p);
294 /* it is one less than actual number of blocks */
295 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
296 }
297 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
298 STREAM_TO_UINT8(p_i93->ic_reference, p);
nxpandroidc7611652015-09-23 16:42:05 +0530299
nxpandroid8f6d0532017-07-12 18:25:30 +0530300 /* clear existing UID to set product version */
301 p_i93->uid[0] = 0x00;
nxpandroidc7611652015-09-23 16:42:05 +0530302
nxpandroid8f6d0532017-07-12 18:25:30 +0530303 /* store UID and get product version */
304 rw_i93_get_product_version(p_uid);
nxpandroidc7611652015-09-23 16:42:05 +0530305
nxpandroid8f6d0532017-07-12 18:25:30 +0530306 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
307 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
308 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
309 p_i93->num_block = 8;
310 p_i93->block_size = 4;
311 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
312 /*
313 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
314 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
315 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
316 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
317 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
318 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
319 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
320 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
321 */
322 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
323 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
324 /*
325 ** M24LR16E-R or M24LR64E-R returns system information
326 ** without memory size, if option flag is not set.
327 ** LRIS64K and M24LR64-R return error if option flag is not
328 ** set.
329 */
330 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
331 /* get memory size with protocol extension flag */
332 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
333 NFC_STATUS_OK) {
334 /* STM supports more than 2040 bytes */
335 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
336
337 return false;
nxpandroidc7611652015-09-23 16:42:05 +0530338 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530339 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530340 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
341 (p_i93->ic_reference == 0x21)) {
342 /* workaround of byte order in memory size information */
343 p_i93->num_block = 64;
344 p_i93->block_size = 4;
nxf24591c1cbeab2018-02-21 17:32:26 +0530345 } else if (!(p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)) {
346 if (!(p_i93->intl_flags & RW_I93_FLAG_EXT_COMMANDS)) {
347 if (rw_i93_send_cmd_get_ext_sys_info(NULL) == NFC_STATUS_OK) {
348 /* STM supports more than 2040 bytes */
349 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
350
351 return false;
352 }
353 }
nxpandroidc7611652015-09-23 16:42:05 +0530354 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530355 }
nxpandroidc7611652015-09-23 16:42:05 +0530356 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530357 }
nxpandroidc7611652015-09-23 16:42:05 +0530358
nxpandroid8f6d0532017-07-12 18:25:30 +0530359 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530360}
361
362/*******************************************************************************
363**
364** Function rw_i93_check_sys_info_prot_ext
365**
nxpandroid8f6d0532017-07-12 18:25:30 +0530366** Description Check if need to set protocol extension flag to get system
367** info
nxpandroidc7611652015-09-23 16:42:05 +0530368**
nxf24591c1cbeab2018-02-21 17:32:26 +0530369** Returns TRUE if sent Get System Info with protocol extension flag
nxpandroidc7611652015-09-23 16:42:05 +0530370**
371*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530372bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
373 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
nxpandroidc7611652015-09-23 16:42:05 +0530374
nxf24591c1cbeab2018-02-21 17:32:26 +0530375 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530376
nxpandroid8f6d0532017-07-12 18:25:30 +0530377 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
378 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
379 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
380 (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
381 NFC_STATUS_OK)) {
382 return true;
383 } else {
384 return false;
385 }
nxpandroidc7611652015-09-23 16:42:05 +0530386}
387
388/*******************************************************************************
389**
390** Function rw_i93_send_to_upper
391**
392** Description Send response to upper layer
393**
394** Returns void
395**
396*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530397void rw_i93_send_to_upper(NFC_HDR* p_resp) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530398 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
nxpandroid8f6d0532017-07-12 18:25:30 +0530399 uint16_t length = p_resp->len;
400 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
401 tRW_DATA rw_data;
402 uint8_t event = RW_I93_MAX_EVT;
403 uint8_t flags;
404 NFC_HDR* p_buff;
nxpandroidc7611652015-09-23 16:42:05 +0530405
nxf24591c1cbeab2018-02-21 17:32:26 +0530406 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530407
nxpandroid8f6d0532017-07-12 18:25:30 +0530408 STREAM_TO_UINT8(flags, p);
409 length--;
nxpandroidc7611652015-09-23 16:42:05 +0530410
nxpandroid8f6d0532017-07-12 18:25:30 +0530411 if (flags & I93_FLAG_ERROR_DETECTED) {
412 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
413 /* getting system info with protocol extension flag */
414 /* This STM tag supports more than 2040 bytes */
415 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
416 p_i93->state = RW_I93_STATE_BUSY;
417 } else {
418 /* notify error to upper layer */
419 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
420 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
421 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
nxpandroidc7611652015-09-23 16:42:05 +0530422
nxpandroid8f6d0532017-07-12 18:25:30 +0530423 rw_cb.tcb.i93.sent_cmd = 0;
424 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +0530425 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530426 return;
427 }
nxpandroidc7611652015-09-23 16:42:05 +0530428
nxpandroid8f6d0532017-07-12 18:25:30 +0530429 switch (p_i93->sent_cmd) {
nxpandroidc7611652015-09-23 16:42:05 +0530430 case I93_CMD_INVENTORY:
431
nxpandroid8f6d0532017-07-12 18:25:30 +0530432 /* forward inventory response */
433 rw_data.i93_inventory.status = NFC_STATUS_OK;
434 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
nxpandroidc7611652015-09-23 16:42:05 +0530435
nxpandroid8f6d0532017-07-12 18:25:30 +0530436 p_uid = rw_data.i93_inventory.uid;
437 STREAM_TO_ARRAY8(p_uid, p);
nxpandroidc7611652015-09-23 16:42:05 +0530438
nxpandroid8f6d0532017-07-12 18:25:30 +0530439 /* store UID and get product version */
440 rw_i93_get_product_version(p_uid);
nxpandroidc7611652015-09-23 16:42:05 +0530441
nxpandroid8f6d0532017-07-12 18:25:30 +0530442 event = RW_I93_INVENTORY_EVT;
443 break;
nxpandroidc7611652015-09-23 16:42:05 +0530444
445 case I93_CMD_READ_SINGLE_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +0530446 case I93_CMD_EXT_READ_SINGLE_BLOCK:
nxpandroidc7611652015-09-23 16:42:05 +0530447 case I93_CMD_READ_MULTI_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +0530448 case I93_CMD_EXT_READ_MULTI_BLOCK:
nxpandroidc7611652015-09-23 16:42:05 +0530449 case I93_CMD_GET_MULTI_BLK_SEC:
nxf24591c1cbeab2018-02-21 17:32:26 +0530450 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
nxpandroidc7611652015-09-23 16:42:05 +0530451
nxpandroid8f6d0532017-07-12 18:25:30 +0530452 /* forward tag data or security status */
453 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
nxpandroidc7611652015-09-23 16:42:05 +0530454
nxpandroid8f6d0532017-07-12 18:25:30 +0530455 if (p_buff) {
456 p_buff->offset = 0;
457 p_buff->len = length;
nxpandroidc7611652015-09-23 16:42:05 +0530458
nxpandroid8f6d0532017-07-12 18:25:30 +0530459 memcpy((p_buff + 1), p, length);
nxpandroidc7611652015-09-23 16:42:05 +0530460
nxpandroid8f6d0532017-07-12 18:25:30 +0530461 rw_data.i93_data.status = NFC_STATUS_OK;
462 rw_data.i93_data.command = p_i93->sent_cmd;
463 rw_data.i93_data.p_data = p_buff;
nxpandroidc7611652015-09-23 16:42:05 +0530464
nxpandroid8f6d0532017-07-12 18:25:30 +0530465 event = RW_I93_DATA_EVT;
466 } else {
467 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
468 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
469 rw_data.i93_cmd_cmpl.error_code = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530470
nxpandroid8f6d0532017-07-12 18:25:30 +0530471 event = RW_I93_CMD_CMPL_EVT;
472 }
473 break;
nxpandroidc7611652015-09-23 16:42:05 +0530474
475 case I93_CMD_WRITE_SINGLE_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +0530476 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
nxpandroidc7611652015-09-23 16:42:05 +0530477 case I93_CMD_LOCK_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +0530478 case I93_CMD_EXT_LOCK_BLOCK:
nxpandroidc7611652015-09-23 16:42:05 +0530479 case I93_CMD_WRITE_MULTI_BLOCK:
nxf24591c1cbeab2018-02-21 17:32:26 +0530480 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
nxpandroidc7611652015-09-23 16:42:05 +0530481 case I93_CMD_SELECT:
482 case I93_CMD_RESET_TO_READY:
483 case I93_CMD_WRITE_AFI:
484 case I93_CMD_LOCK_AFI:
485 case I93_CMD_WRITE_DSFID:
486 case I93_CMD_LOCK_DSFID:
487
nxpandroid8f6d0532017-07-12 18:25:30 +0530488 /* notify the complete of command */
489 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
490 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
491 rw_data.i93_cmd_cmpl.error_code = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530492
nxpandroid8f6d0532017-07-12 18:25:30 +0530493 event = RW_I93_CMD_CMPL_EVT;
494 break;
nxpandroidc7611652015-09-23 16:42:05 +0530495
496 case I93_CMD_GET_SYS_INFO:
497
nxpandroid8f6d0532017-07-12 18:25:30 +0530498 if (rw_i93_process_sys_info(p)) {
499 rw_data.i93_sys_info.status = NFC_STATUS_OK;
500 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
501 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
502 rw_data.i93_sys_info.afi = p_i93->afi;
503 rw_data.i93_sys_info.num_block = p_i93->num_block;
504 rw_data.i93_sys_info.block_size = p_i93->block_size;
505 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
nxpandroidc7611652015-09-23 16:42:05 +0530506
nxpandroid8f6d0532017-07-12 18:25:30 +0530507 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530508
nxpandroid8f6d0532017-07-12 18:25:30 +0530509 event = RW_I93_SYS_INFO_EVT;
510 } else {
511 /* retrying with protocol extension flag */
512 p_i93->state = RW_I93_STATE_BUSY;
513 return;
514 }
515 break;
nxpandroidc7611652015-09-23 16:42:05 +0530516
nxf24591c1cbeab2018-02-21 17:32:26 +0530517 case I93_CMD_EXT_GET_SYS_INFO:
518
519 if (rw_i93_process_ext_sys_info(p)) {
520 rw_data.i93_sys_info.status = NFC_STATUS_OK;
521 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
522 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
523 rw_data.i93_sys_info.afi = p_i93->afi;
524 rw_data.i93_sys_info.num_block = p_i93->num_block;
525 rw_data.i93_sys_info.block_size = p_i93->block_size;
526 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
527
528 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
529
530 event = RW_I93_SYS_INFO_EVT;
531 } else {
532 /* retrying with protocol extension flag or with extended sys info
533 * command */
534 p_i93->state = RW_I93_STATE_BUSY;
535 return;
536 }
537 break;
538
nxpandroidc7611652015-09-23 16:42:05 +0530539 default:
nxpandroid8f6d0532017-07-12 18:25:30 +0530540 break;
541 }
nxpandroidc7611652015-09-23 16:42:05 +0530542
nxpandroid8f6d0532017-07-12 18:25:30 +0530543 rw_cb.tcb.i93.sent_cmd = 0;
544 if (event != RW_I93_MAX_EVT) {
545 (*(rw_cb.p_cback))(event, &rw_data);
546 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +0530547 LOG(ERROR) << StringPrintf("Invalid response");
nxpandroid8f6d0532017-07-12 18:25:30 +0530548 }
nxpandroidc7611652015-09-23 16:42:05 +0530549}
550
551/*******************************************************************************
552**
553** Function rw_i93_send_to_lower
554**
555** Description Send Request frame to lower layer
556**
nxf24591c1cbeab2018-02-21 17:32:26 +0530557** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530558**
559*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530560bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530561 /* store command for retransmitting */
562 if (rw_cb.tcb.i93.p_retry_cmd) {
563 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
564 rw_cb.tcb.i93.p_retry_cmd = NULL;
565 }
nxpandroidc7611652015-09-23 16:42:05 +0530566
nxpandroid8f6d0532017-07-12 18:25:30 +0530567 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530568
nxpandroid8f6d0532017-07-12 18:25:30 +0530569 if (rw_cb.tcb.i93.p_retry_cmd) {
570 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
571 sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
572 }
nxpandroidc7611652015-09-23 16:42:05 +0530573
nxpandroid8f6d0532017-07-12 18:25:30 +0530574 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530575 LOG(ERROR) << StringPrintf("failed");
nxpandroid8f6d0532017-07-12 18:25:30 +0530576 return false;
577 }
nxpandroidc7611652015-09-23 16:42:05 +0530578
nxpandroid8f6d0532017-07-12 18:25:30 +0530579 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
580 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530581
nxpandroid8f6d0532017-07-12 18:25:30 +0530582 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530583}
584
585/*******************************************************************************
586**
587** Function rw_i93_send_cmd_inventory
588**
589** Description Send Inventory Request to VICC
590**
591** Returns tNFC_STATUS
592**
593*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530594tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
595 uint8_t afi) {
596 NFC_HDR* p_cmd;
nxf24591c1cbeab2018-02-21 17:32:26 +0530597 uint8_t *p, flags;
nxpandroidc7611652015-09-23 16:42:05 +0530598
nxf24591c1cbeab2018-02-21 17:32:26 +0530599 DLOG_IF(INFO, nfc_debug_enabled)
600 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
nxpandroidc7611652015-09-23 16:42:05 +0530601
nxpandroid8f6d0532017-07-12 18:25:30 +0530602 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530603
nxpandroid8f6d0532017-07-12 18:25:30 +0530604 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530605 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530606 return NFC_STATUS_NO_BUFFERS;
607 }
nxpandroidc7611652015-09-23 16:42:05 +0530608
nxpandroid8f6d0532017-07-12 18:25:30 +0530609 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
610 p_cmd->len = 3;
611 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530612
nxpandroid8f6d0532017-07-12 18:25:30 +0530613 /* Flags */
614 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
615 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
616 if (including_afi) {
617 flags |= I93_FLAG_AFI_PRESENT;
618 }
nxpandroidc7611652015-09-23 16:42:05 +0530619
nxpandroid8f6d0532017-07-12 18:25:30 +0530620 UINT8_TO_STREAM(p, flags);
nxpandroidc7611652015-09-23 16:42:05 +0530621
nxpandroid8f6d0532017-07-12 18:25:30 +0530622 /* Command Code */
623 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
nxpandroidc7611652015-09-23 16:42:05 +0530624
nxpandroid8f6d0532017-07-12 18:25:30 +0530625 if (including_afi) {
626 /* Parameters */
627 UINT8_TO_STREAM(p, afi); /* Optional AFI */
628 p_cmd->len++;
629 }
nxpandroidc7611652015-09-23 16:42:05 +0530630
nxpandroid8f6d0532017-07-12 18:25:30 +0530631 if (p_uid) {
632 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
633 ARRAY8_TO_STREAM(p, p_uid); /* UID */
634 p_cmd->len += I93_UID_BYTE_LEN;
635 } else {
636 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
637 }
nxpandroidc7611652015-09-23 16:42:05 +0530638
nxpandroid8f6d0532017-07-12 18:25:30 +0530639 if (rw_i93_send_to_lower(p_cmd)) {
640 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
641 return NFC_STATUS_OK;
642 } else {
643 return NFC_STATUS_FAILED;
644 }
nxpandroidc7611652015-09-23 16:42:05 +0530645}
646
647/*******************************************************************************
648**
649** Function rw_i93_send_cmd_stay_quiet
650**
651** Description Send Stay Quiet Request to VICC
652**
653** Returns tNFC_STATUS
654**
655*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530656tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
657 NFC_HDR* p_cmd;
658 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530659
nxf24591c1cbeab2018-02-21 17:32:26 +0530660 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530661
nxpandroid8f6d0532017-07-12 18:25:30 +0530662 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530663
nxpandroid8f6d0532017-07-12 18:25:30 +0530664 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530665 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530666 return NFC_STATUS_NO_BUFFERS;
667 }
nxpandroidc7611652015-09-23 16:42:05 +0530668
nxpandroid8f6d0532017-07-12 18:25:30 +0530669 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
670 p_cmd->len = 10;
671 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530672
nxpandroid8f6d0532017-07-12 18:25:30 +0530673 /* Flags */
674 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
675 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +0530676
nxpandroid8f6d0532017-07-12 18:25:30 +0530677 /* Command Code */
678 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
nxpandroidc7611652015-09-23 16:42:05 +0530679
nxpandroid8f6d0532017-07-12 18:25:30 +0530680 /* Parameters */
681 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +0530682
nxpandroid8f6d0532017-07-12 18:25:30 +0530683 if (rw_i93_send_to_lower(p_cmd)) {
684 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
nxpandroidc7611652015-09-23 16:42:05 +0530685
nxpandroid8f6d0532017-07-12 18:25:30 +0530686 /* restart timer for stay quiet */
687 nfc_start_quick_timer(
688 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
689 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
690 return NFC_STATUS_OK;
691 } else {
692 return NFC_STATUS_FAILED;
693 }
nxpandroidc7611652015-09-23 16:42:05 +0530694}
695
696/*******************************************************************************
697**
698** Function rw_i93_send_cmd_read_single_block
699**
700** Description Send Read Single Block Request to VICC
701**
702** Returns tNFC_STATUS
703**
704*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530705tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
706 bool read_security) {
707 NFC_HDR* p_cmd;
nxf24591c1cbeab2018-02-21 17:32:26 +0530708 uint8_t *p, flags;
nxpandroidc7611652015-09-23 16:42:05 +0530709
nxf24591c1cbeab2018-02-21 17:32:26 +0530710 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530711
nxpandroid8f6d0532017-07-12 18:25:30 +0530712 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530713
nxpandroid8f6d0532017-07-12 18:25:30 +0530714 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530715 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530716 return NFC_STATUS_NO_BUFFERS;
717 }
nxpandroidc7611652015-09-23 16:42:05 +0530718
nxpandroid8f6d0532017-07-12 18:25:30 +0530719 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
720 p_cmd->len = 11;
721 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530722
nxpandroid8f6d0532017-07-12 18:25:30 +0530723 /* Flags */
724 flags =
725 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
nxpandroidc7611652015-09-23 16:42:05 +0530726
nxpandroid8f6d0532017-07-12 18:25:30 +0530727 if (read_security) flags |= I93_FLAG_OPTION_SET;
nxpandroidc7611652015-09-23 16:42:05 +0530728
nxpandroid8f6d0532017-07-12 18:25:30 +0530729 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
730 flags |= I93_FLAG_PROT_EXT_YES;
nxpandroidc7611652015-09-23 16:42:05 +0530731
nxpandroid8f6d0532017-07-12 18:25:30 +0530732 UINT8_TO_STREAM(p, flags);
nxpandroidc7611652015-09-23 16:42:05 +0530733
nxpandroid8f6d0532017-07-12 18:25:30 +0530734 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +0530735 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
736 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_SINGLE_BLOCK);
737 } else {
738 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
739 }
nxpandroidc7611652015-09-23 16:42:05 +0530740
nxpandroid8f6d0532017-07-12 18:25:30 +0530741 /* Parameters */
742 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +0530743
nxf24591c1cbeab2018-02-21 17:32:26 +0530744 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
745 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530746 UINT16_TO_STREAM(p, block_number); /* Block number */
747 p_cmd->len++;
748 } else {
749 UINT8_TO_STREAM(p, block_number); /* Block number */
750 }
nxpandroidc7611652015-09-23 16:42:05 +0530751
nxpandroid8f6d0532017-07-12 18:25:30 +0530752 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530753 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
754 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_SINGLE_BLOCK;
755 else
756 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
nxpandroid8f6d0532017-07-12 18:25:30 +0530757 return NFC_STATUS_OK;
758 } else {
759 return NFC_STATUS_FAILED;
760 }
nxpandroidc7611652015-09-23 16:42:05 +0530761}
762
763/*******************************************************************************
764**
765** Function rw_i93_send_cmd_write_single_block
766**
767** Description Send Write Single Block Request to VICC
768**
769** Returns tNFC_STATUS
770**
771*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530772tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
773 uint8_t* p_data) {
774 NFC_HDR* p_cmd;
nxf24591c1cbeab2018-02-21 17:32:26 +0530775 uint8_t *p, flags;
nxpandroidc7611652015-09-23 16:42:05 +0530776
nxf24591c1cbeab2018-02-21 17:32:26 +0530777 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530778
nxpandroid8f6d0532017-07-12 18:25:30 +0530779 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530780
nxpandroid8f6d0532017-07-12 18:25:30 +0530781 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530782 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530783 return NFC_STATUS_NO_BUFFERS;
784 }
nxpandroidc7611652015-09-23 16:42:05 +0530785
nxpandroid8f6d0532017-07-12 18:25:30 +0530786 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
787 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
788 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530789
nxpandroid8f6d0532017-07-12 18:25:30 +0530790 /* Flags */
791 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
792 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
793 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
794 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
795 /* Option must be set for TI tag */
796 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
797 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
798 } else {
799 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
800 RW_I93_FLAG_DATA_RATE);
801 }
nxpandroidc7611652015-09-23 16:42:05 +0530802
nxpandroid8f6d0532017-07-12 18:25:30 +0530803 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
804 flags |= I93_FLAG_PROT_EXT_YES;
nxpandroidc7611652015-09-23 16:42:05 +0530805
nxpandroid8f6d0532017-07-12 18:25:30 +0530806 UINT8_TO_STREAM(p, flags);
nxpandroidc7611652015-09-23 16:42:05 +0530807
nxpandroid8f6d0532017-07-12 18:25:30 +0530808 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +0530809 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
810 UINT8_TO_STREAM(p, I93_CMD_EXT_WRITE_SINGLE_BLOCK);
811 } else {
812 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
813 }
nxpandroidc7611652015-09-23 16:42:05 +0530814
nxpandroid8f6d0532017-07-12 18:25:30 +0530815 /* Parameters */
816 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +0530817
nxf24591c1cbeab2018-02-21 17:32:26 +0530818 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
819 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530820 UINT16_TO_STREAM(p, block_number); /* Block number */
821 p_cmd->len++;
822 } else {
823 UINT8_TO_STREAM(p, block_number); /* Block number */
824 }
nxpandroidc7611652015-09-23 16:42:05 +0530825
nxpandroid8f6d0532017-07-12 18:25:30 +0530826 /* Data */
827 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
nxpandroidc7611652015-09-23 16:42:05 +0530828
nxpandroid8f6d0532017-07-12 18:25:30 +0530829 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530830 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
831 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_SINGLE_BLOCK;
832 else
833 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
nxpandroid8f6d0532017-07-12 18:25:30 +0530834 return NFC_STATUS_OK;
835 } else {
836 return NFC_STATUS_FAILED;
837 }
nxpandroidc7611652015-09-23 16:42:05 +0530838}
839
840/*******************************************************************************
841**
842** Function rw_i93_send_cmd_lock_block
843**
844** Description Send Lock Block Request to VICC
845**
846** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
847** do not support.
848**
849** Returns tNFC_STATUS
850**
851*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530852tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
853 NFC_HDR* p_cmd;
854 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530855
nxf24591c1cbeab2018-02-21 17:32:26 +0530856 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530857
nxpandroid8f6d0532017-07-12 18:25:30 +0530858 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530859
nxpandroid8f6d0532017-07-12 18:25:30 +0530860 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530861 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530862 return NFC_STATUS_NO_BUFFERS;
863 }
nxpandroidc7611652015-09-23 16:42:05 +0530864
nxpandroid8f6d0532017-07-12 18:25:30 +0530865 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
866 p_cmd->len = 11;
867 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530868
nxpandroid8f6d0532017-07-12 18:25:30 +0530869 /* Flags */
870 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
871 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
872 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
873 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
874 /* Option must be set for TI tag */
875 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
876 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
877 } else {
878 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
879 RW_I93_FLAG_DATA_RATE));
880 }
nxpandroidc7611652015-09-23 16:42:05 +0530881
nxpandroid8f6d0532017-07-12 18:25:30 +0530882 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +0530883 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
884 UINT8_TO_STREAM(p, I93_CMD_EXT_LOCK_BLOCK);
885 } else {
886 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
887 }
nxpandroidc7611652015-09-23 16:42:05 +0530888
nxpandroid8f6d0532017-07-12 18:25:30 +0530889 /* Parameters */
890 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxf24591c1cbeab2018-02-21 17:32:26 +0530891
892 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
893 UINT16_TO_STREAM(p, block_number); /* Block number */
894 p_cmd->len++;
895 } else {
896 UINT8_TO_STREAM(p, block_number); /* Block number */
897 }
nxpandroidc7611652015-09-23 16:42:05 +0530898
nxpandroid8f6d0532017-07-12 18:25:30 +0530899 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530900 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
901 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_LOCK_BLOCK;
902 else
903 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
nxpandroid8f6d0532017-07-12 18:25:30 +0530904 return NFC_STATUS_OK;
905 } else {
906 return NFC_STATUS_FAILED;
907 }
nxpandroidc7611652015-09-23 16:42:05 +0530908}
909
910/*******************************************************************************
911**
912** Function rw_i93_send_cmd_read_multi_blocks
913**
914** Description Send Read Multiple Blocks Request to VICC
915**
916** Returns tNFC_STATUS
917**
918*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530919tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
920 uint16_t number_blocks) {
921 NFC_HDR* p_cmd;
nxf24591c1cbeab2018-02-21 17:32:26 +0530922 uint8_t *p, flags;
nxpandroidc7611652015-09-23 16:42:05 +0530923
nxf24591c1cbeab2018-02-21 17:32:26 +0530924 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530925
nxpandroid8f6d0532017-07-12 18:25:30 +0530926 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530927
nxpandroid8f6d0532017-07-12 18:25:30 +0530928 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530929 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530930 return NFC_STATUS_NO_BUFFERS;
931 }
nxpandroidc7611652015-09-23 16:42:05 +0530932
nxpandroid8f6d0532017-07-12 18:25:30 +0530933 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
934 p_cmd->len = 12;
935 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530936
nxpandroid8f6d0532017-07-12 18:25:30 +0530937 /* Flags */
938 flags =
939 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
nxpandroidc7611652015-09-23 16:42:05 +0530940
nxf24591c1cbeab2018-02-21 17:32:26 +0530941 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530942 flags |= I93_FLAG_PROT_EXT_YES;
nxf24591c1cbeab2018-02-21 17:32:26 +0530943 }
nxpandroidc7611652015-09-23 16:42:05 +0530944
nxpandroid8f6d0532017-07-12 18:25:30 +0530945 UINT8_TO_STREAM(p, flags);
nxpandroidc7611652015-09-23 16:42:05 +0530946
nxpandroid8f6d0532017-07-12 18:25:30 +0530947 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +0530948 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
949 UINT8_TO_STREAM(p, I93_CMD_EXT_READ_MULTI_BLOCK);
950 } else {
951 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
952 }
nxpandroidc7611652015-09-23 16:42:05 +0530953
nxpandroid8f6d0532017-07-12 18:25:30 +0530954 /* Parameters */
955 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +0530956
nxf24591c1cbeab2018-02-21 17:32:26 +0530957 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
958 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530959 UINT16_TO_STREAM(p, first_block_number); /* First block number */
960 p_cmd->len++;
961 } else {
962 UINT8_TO_STREAM(p, first_block_number); /* First block number */
963 }
nxpandroidc7611652015-09-23 16:42:05 +0530964
nxf24591c1cbeab2018-02-21 17:32:26 +0530965 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
966 UINT16_TO_STREAM(
967 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
968 p_cmd->len++;
969 } else {
970 UINT8_TO_STREAM(
971 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
972 }
nxpandroidc7611652015-09-23 16:42:05 +0530973
nxpandroid8f6d0532017-07-12 18:25:30 +0530974 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530975 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
976 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_READ_MULTI_BLOCK;
977 else
978 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
nxpandroid8f6d0532017-07-12 18:25:30 +0530979 return NFC_STATUS_OK;
980 } else {
981 return NFC_STATUS_FAILED;
982 }
nxpandroidc7611652015-09-23 16:42:05 +0530983}
984
985/*******************************************************************************
986**
987** Function rw_i93_send_cmd_write_multi_blocks
988**
989** Description Send Write Multiple Blocks Request to VICC
990**
991** Returns tNFC_STATUS
992**
993*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +0530994tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
nxpandroid8f6d0532017-07-12 18:25:30 +0530995 uint16_t number_blocks,
996 uint8_t* p_data) {
997 NFC_HDR* p_cmd;
998 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530999
nxf24591c1cbeab2018-02-21 17:32:26 +05301000 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301001
nxpandroid8f6d0532017-07-12 18:25:30 +05301002 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301003
nxpandroid8f6d0532017-07-12 18:25:30 +05301004 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301005 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301006 return NFC_STATUS_NO_BUFFERS;
1007 }
nxpandroidc7611652015-09-23 16:42:05 +05301008
nxpandroid8f6d0532017-07-12 18:25:30 +05301009 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1010 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
1011 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301012
nxpandroid8f6d0532017-07-12 18:25:30 +05301013 /* Flags */
1014 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1015 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301016
nxpandroid8f6d0532017-07-12 18:25:30 +05301017 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301018 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1019 INT8_TO_STREAM(p, I93_CMD_EXT_WRITE_MULTI_BLOCK);
1020 } else {
1021 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
1022 }
nxpandroidc7611652015-09-23 16:42:05 +05301023
nxpandroid8f6d0532017-07-12 18:25:30 +05301024 /* Parameters */
1025 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxf24591c1cbeab2018-02-21 17:32:26 +05301026 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1027 UINT16_TO_STREAM(p, first_block_number); /* Block number */
1028 UINT16_TO_STREAM(
1029 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1030 p_cmd->len += 2;
1031 } else {
1032 UINT8_TO_STREAM(p, first_block_number); /* Block number */
1033 UINT8_TO_STREAM(
1034 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1035 }
1036
nxpandroid8f6d0532017-07-12 18:25:30 +05301037 UINT8_TO_STREAM(
1038 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
nxpandroidc7611652015-09-23 16:42:05 +05301039
nxpandroid8f6d0532017-07-12 18:25:30 +05301040 /* Data */
1041 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
nxpandroidc7611652015-09-23 16:42:05 +05301042
nxpandroid8f6d0532017-07-12 18:25:30 +05301043 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301044 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1045 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_WRITE_MULTI_BLOCK;
1046 else
1047 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
nxpandroid8f6d0532017-07-12 18:25:30 +05301048 return NFC_STATUS_OK;
1049 } else {
1050 return NFC_STATUS_FAILED;
1051 }
nxpandroidc7611652015-09-23 16:42:05 +05301052}
1053
1054/*******************************************************************************
1055**
1056** Function rw_i93_send_cmd_select
1057**
1058** Description Send Select Request to VICC
1059**
1060** Returns tNFC_STATUS
1061**
1062*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301063tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1064 NFC_HDR* p_cmd;
1065 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301066
nxf24591c1cbeab2018-02-21 17:32:26 +05301067 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301068
nxpandroid8f6d0532017-07-12 18:25:30 +05301069 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301070
nxpandroid8f6d0532017-07-12 18:25:30 +05301071 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301072 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301073 return NFC_STATUS_NO_BUFFERS;
1074 }
nxpandroidc7611652015-09-23 16:42:05 +05301075
nxpandroid8f6d0532017-07-12 18:25:30 +05301076 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1077 p_cmd->len = 10;
1078 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301079
nxpandroid8f6d0532017-07-12 18:25:30 +05301080 /* Flags */
1081 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1082 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301083
nxpandroid8f6d0532017-07-12 18:25:30 +05301084 /* Command Code */
1085 UINT8_TO_STREAM(p, I93_CMD_SELECT);
nxpandroidc7611652015-09-23 16:42:05 +05301086
nxpandroid8f6d0532017-07-12 18:25:30 +05301087 /* Parameters */
1088 ARRAY8_TO_STREAM(p, p_uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +05301089
nxpandroid8f6d0532017-07-12 18:25:30 +05301090 if (rw_i93_send_to_lower(p_cmd)) {
1091 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
1092 return NFC_STATUS_OK;
1093 } else {
1094 return NFC_STATUS_FAILED;
1095 }
nxpandroidc7611652015-09-23 16:42:05 +05301096}
1097
1098/*******************************************************************************
1099**
1100** Function rw_i93_send_cmd_reset_to_ready
1101**
1102** Description Send Reset to Ready Request to VICC
1103**
1104** Returns tNFC_STATUS
1105**
1106*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301107tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1108 NFC_HDR* p_cmd;
1109 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301110
nxf24591c1cbeab2018-02-21 17:32:26 +05301111 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301112
nxpandroid8f6d0532017-07-12 18:25:30 +05301113 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301114
nxpandroid8f6d0532017-07-12 18:25:30 +05301115 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301116 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301117 return NFC_STATUS_NO_BUFFERS;
1118 }
nxpandroidc7611652015-09-23 16:42:05 +05301119
nxpandroid8f6d0532017-07-12 18:25:30 +05301120 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1121 p_cmd->len = 10;
1122 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301123
nxpandroid8f6d0532017-07-12 18:25:30 +05301124 /* Flags */
1125 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1126 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301127
nxpandroid8f6d0532017-07-12 18:25:30 +05301128 /* Command Code */
1129 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
nxpandroidc7611652015-09-23 16:42:05 +05301130
nxpandroid8f6d0532017-07-12 18:25:30 +05301131 /* Parameters */
1132 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +05301133
nxpandroid8f6d0532017-07-12 18:25:30 +05301134 if (rw_i93_send_to_lower(p_cmd)) {
1135 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1136 return NFC_STATUS_OK;
1137 } else {
1138 return NFC_STATUS_FAILED;
1139 }
nxpandroidc7611652015-09-23 16:42:05 +05301140}
1141
1142/*******************************************************************************
1143**
1144** Function rw_i93_send_cmd_write_afi
1145**
1146** Description Send Write AFI Request to VICC
1147**
1148** Returns tNFC_STATUS
1149**
1150*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301151tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1152 NFC_HDR* p_cmd;
1153 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301154
nxf24591c1cbeab2018-02-21 17:32:26 +05301155 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301156
nxpandroid8f6d0532017-07-12 18:25:30 +05301157 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301158
nxpandroid8f6d0532017-07-12 18:25:30 +05301159 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301160 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301161 return NFC_STATUS_NO_BUFFERS;
1162 }
nxpandroidc7611652015-09-23 16:42:05 +05301163
nxpandroid8f6d0532017-07-12 18:25:30 +05301164 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1165 p_cmd->len = 11;
1166 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301167
nxpandroid8f6d0532017-07-12 18:25:30 +05301168 /* Flags */
1169 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1170 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301171
nxpandroid8f6d0532017-07-12 18:25:30 +05301172 /* Command Code */
1173 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
nxpandroidc7611652015-09-23 16:42:05 +05301174
nxpandroid8f6d0532017-07-12 18:25:30 +05301175 /* Parameters */
1176 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1177 UINT8_TO_STREAM(p, afi); /* AFI */
nxpandroidc7611652015-09-23 16:42:05 +05301178
nxpandroid8f6d0532017-07-12 18:25:30 +05301179 if (rw_i93_send_to_lower(p_cmd)) {
1180 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1181 return NFC_STATUS_OK;
1182 } else {
1183 return NFC_STATUS_FAILED;
1184 }
nxpandroidc7611652015-09-23 16:42:05 +05301185}
1186
1187/*******************************************************************************
1188**
1189** Function rw_i93_send_cmd_lock_afi
1190**
1191** Description Send Lock AFI Request to VICC
1192**
1193** Returns tNFC_STATUS
1194**
1195*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301196tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1197 NFC_HDR* p_cmd;
1198 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301199
nxf24591c1cbeab2018-02-21 17:32:26 +05301200 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301201
nxpandroid8f6d0532017-07-12 18:25:30 +05301202 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301203
nxpandroid8f6d0532017-07-12 18:25:30 +05301204 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301205 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301206 return NFC_STATUS_NO_BUFFERS;
1207 }
nxpandroidc7611652015-09-23 16:42:05 +05301208
nxpandroid8f6d0532017-07-12 18:25:30 +05301209 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1210 p_cmd->len = 10;
1211 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301212
nxpandroid8f6d0532017-07-12 18:25:30 +05301213 /* Flags */
1214 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1215 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301216
nxpandroid8f6d0532017-07-12 18:25:30 +05301217 /* Command Code */
1218 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
nxpandroidc7611652015-09-23 16:42:05 +05301219
nxpandroid8f6d0532017-07-12 18:25:30 +05301220 /* Parameters */
1221 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +05301222
nxpandroid8f6d0532017-07-12 18:25:30 +05301223 if (rw_i93_send_to_lower(p_cmd)) {
1224 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1225 return NFC_STATUS_OK;
1226 } else {
1227 return NFC_STATUS_FAILED;
1228 }
nxpandroidc7611652015-09-23 16:42:05 +05301229}
1230
1231/*******************************************************************************
1232**
1233** Function rw_i93_send_cmd_write_dsfid
1234**
1235** Description Send Write DSFID Request to VICC
1236**
1237** Returns tNFC_STATUS
1238**
1239*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301240tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1241 NFC_HDR* p_cmd;
1242 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301243
nxf24591c1cbeab2018-02-21 17:32:26 +05301244 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301245
nxpandroid8f6d0532017-07-12 18:25:30 +05301246 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301247
nxpandroid8f6d0532017-07-12 18:25:30 +05301248 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301249 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301250 return NFC_STATUS_NO_BUFFERS;
1251 }
nxpandroidc7611652015-09-23 16:42:05 +05301252
nxpandroid8f6d0532017-07-12 18:25:30 +05301253 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1254 p_cmd->len = 11;
1255 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301256
nxpandroid8f6d0532017-07-12 18:25:30 +05301257 /* Flags */
1258 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1259 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301260
nxpandroid8f6d0532017-07-12 18:25:30 +05301261 /* Command Code */
1262 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
nxpandroidc7611652015-09-23 16:42:05 +05301263
nxpandroid8f6d0532017-07-12 18:25:30 +05301264 /* Parameters */
1265 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1266 UINT8_TO_STREAM(p, dsfid); /* DSFID */
nxpandroidc7611652015-09-23 16:42:05 +05301267
nxpandroid8f6d0532017-07-12 18:25:30 +05301268 if (rw_i93_send_to_lower(p_cmd)) {
1269 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1270 return NFC_STATUS_OK;
1271 } else {
1272 return NFC_STATUS_FAILED;
1273 }
nxpandroidc7611652015-09-23 16:42:05 +05301274}
1275
1276/*******************************************************************************
1277**
1278** Function rw_i93_send_cmd_lock_dsfid
1279**
1280** Description Send Lock DSFID Request to VICC
1281**
1282** Returns tNFC_STATUS
1283**
1284*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301285tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1286 NFC_HDR* p_cmd;
1287 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301288
nxf24591c1cbeab2018-02-21 17:32:26 +05301289 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301290
nxpandroid8f6d0532017-07-12 18:25:30 +05301291 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301292
nxpandroid8f6d0532017-07-12 18:25:30 +05301293 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301294 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301295 return NFC_STATUS_NO_BUFFERS;
1296 }
nxpandroidc7611652015-09-23 16:42:05 +05301297
nxpandroid8f6d0532017-07-12 18:25:30 +05301298 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1299 p_cmd->len = 10;
1300 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301301
nxpandroid8f6d0532017-07-12 18:25:30 +05301302 /* Flags */
1303 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1304 RW_I93_FLAG_DATA_RATE));
nxpandroidc7611652015-09-23 16:42:05 +05301305
nxpandroid8f6d0532017-07-12 18:25:30 +05301306 /* Command Code */
1307 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
nxpandroidc7611652015-09-23 16:42:05 +05301308
nxpandroid8f6d0532017-07-12 18:25:30 +05301309 /* Parameters */
1310 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +05301311
nxpandroid8f6d0532017-07-12 18:25:30 +05301312 if (rw_i93_send_to_lower(p_cmd)) {
1313 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1314 return NFC_STATUS_OK;
1315 } else {
1316 return NFC_STATUS_FAILED;
1317 }
nxpandroidc7611652015-09-23 16:42:05 +05301318}
1319
1320/*******************************************************************************
1321**
nxf24591c1cbeab2018-02-21 17:32:26 +05301322** Function rw_i93_send_cmd_get_ext_sys_info
1323**
1324** Description Send Get Extended System Information Request to VICC
1325**
1326** Returns tNFC_STATUS
1327**
1328*******************************************************************************/
1329tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid) {
1330 NFC_HDR* p_cmd;
1331 uint8_t* p;
1332
1333 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1334
1335 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1336
1337 if (!p_cmd) {
1338 DLOG_IF(INFO, nfc_debug_enabled) << __func__ << "Cannot allocate buffer";
1339 return NFC_STATUS_NO_BUFFERS;
1340 }
1341
1342 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1343 p_cmd->len = 11;
1344 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1345
1346 /* Flags */
1347 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1348 RW_I93_FLAG_DATA_RATE));
1349
1350 /* Command Code */
1351 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_SYS_INFO);
1352
1353 /* Parameters request field */
1354 UINT8_TO_STREAM(p,
1355 (I93_INFO_FLAG_MOI | I93_INFO_FLAG_DSFID | I93_INFO_FLAG_AFI |
1356 I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_IC_REF));
1357
1358 /* Parameters */
1359 if (p_uid) {
1360 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1361 } else {
1362 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1363 }
1364
1365 if (rw_i93_send_to_lower(p_cmd)) {
1366 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_SYS_INFO;
1367 return NFC_STATUS_OK;
1368 } else {
1369 return NFC_STATUS_FAILED;
1370 }
1371}
1372
1373/*******************************************************************************
1374**
nxpandroidc7611652015-09-23 16:42:05 +05301375** Function rw_i93_send_cmd_get_sys_info
1376**
1377** Description Send Get System Information Request to VICC
1378**
1379** Returns tNFC_STATUS
1380**
1381*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301382tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1383 NFC_HDR* p_cmd;
1384 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +05301385
nxf24591c1cbeab2018-02-21 17:32:26 +05301386 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301387
nxpandroid8f6d0532017-07-12 18:25:30 +05301388 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301389
nxpandroid8f6d0532017-07-12 18:25:30 +05301390 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301391 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301392 return NFC_STATUS_NO_BUFFERS;
1393 }
nxpandroidc7611652015-09-23 16:42:05 +05301394
nxpandroid8f6d0532017-07-12 18:25:30 +05301395 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1396 p_cmd->len = 10;
1397 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301398
nxpandroid8f6d0532017-07-12 18:25:30 +05301399 /* Flags */
1400 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1401 RW_I93_FLAG_DATA_RATE | extra_flags));
nxpandroidc7611652015-09-23 16:42:05 +05301402
nxpandroid8f6d0532017-07-12 18:25:30 +05301403 /* Command Code */
1404 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
nxpandroidc7611652015-09-23 16:42:05 +05301405
nxpandroid8f6d0532017-07-12 18:25:30 +05301406 /* Parameters */
1407 if (p_uid) {
1408 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1409 } else {
1410 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1411 }
nxpandroidc7611652015-09-23 16:42:05 +05301412
nxpandroid8f6d0532017-07-12 18:25:30 +05301413 if (rw_i93_send_to_lower(p_cmd)) {
1414 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1415 return NFC_STATUS_OK;
1416 } else {
1417 return NFC_STATUS_FAILED;
1418 }
nxpandroidc7611652015-09-23 16:42:05 +05301419}
1420
1421/*******************************************************************************
1422**
1423** Function rw_i93_send_cmd_get_multi_block_sec
1424**
1425** Description Send Get Multiple Block Security Status Request to VICC
1426**
1427** Returns tNFC_STATUS
1428**
1429*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301430tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1431 uint16_t number_blocks) {
1432 NFC_HDR* p_cmd;
nxf24591c1cbeab2018-02-21 17:32:26 +05301433 uint8_t *p, flags;
nxpandroidc7611652015-09-23 16:42:05 +05301434
nxf24591c1cbeab2018-02-21 17:32:26 +05301435 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301436
nxpandroid8f6d0532017-07-12 18:25:30 +05301437 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +05301438
nxpandroid8f6d0532017-07-12 18:25:30 +05301439 if (!p_cmd) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301440 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05301441 return NFC_STATUS_NO_BUFFERS;
1442 }
nxpandroidc7611652015-09-23 16:42:05 +05301443
nxpandroid8f6d0532017-07-12 18:25:30 +05301444 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1445 p_cmd->len = 12;
1446 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301447
nxpandroid8f6d0532017-07-12 18:25:30 +05301448 /* Flags */
1449 flags =
1450 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
nxpandroidc7611652015-09-23 16:42:05 +05301451
nxpandroid8f6d0532017-07-12 18:25:30 +05301452 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1453 flags |= I93_FLAG_PROT_EXT_YES;
nxpandroidc7611652015-09-23 16:42:05 +05301454
nxpandroid8f6d0532017-07-12 18:25:30 +05301455 UINT8_TO_STREAM(p, flags);
nxpandroidc7611652015-09-23 16:42:05 +05301456
nxpandroid8f6d0532017-07-12 18:25:30 +05301457 /* Command Code */
nxf24591c1cbeab2018-02-21 17:32:26 +05301458 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
1459 UINT8_TO_STREAM(p, I93_CMD_EXT_GET_MULTI_BLK_SEC);
1460 } else {
1461 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1462 }
nxpandroidc7611652015-09-23 16:42:05 +05301463
nxpandroid8f6d0532017-07-12 18:25:30 +05301464 /* Parameters */
1465 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
nxpandroidc7611652015-09-23 16:42:05 +05301466
nxf24591c1cbeab2018-02-21 17:32:26 +05301467 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK ||
1468 rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301469 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1470 UINT16_TO_STREAM(
1471 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1472 p_cmd->len += 2;
1473 } else {
1474 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1475 UINT8_TO_STREAM(
1476 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1477 }
nxpandroidc7611652015-09-23 16:42:05 +05301478
nxpandroid8f6d0532017-07-12 18:25:30 +05301479 if (rw_i93_send_to_lower(p_cmd)) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301480 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_EXT_COMMANDS)
1481 rw_cb.tcb.i93.sent_cmd = I93_CMD_EXT_GET_MULTI_BLK_SEC;
1482 else
1483 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
nxpandroid8f6d0532017-07-12 18:25:30 +05301484 return NFC_STATUS_OK;
1485 } else {
1486 return NFC_STATUS_FAILED;
1487 }
nxpandroidc7611652015-09-23 16:42:05 +05301488}
1489
1490/*******************************************************************************
1491**
1492** Function rw_i93_get_next_blocks
1493**
nxpandroid8f6d0532017-07-12 18:25:30 +05301494** Description Read as many blocks as possible (up to
1495** RW_I93_READ_MULTI_BLOCK_SIZE)
nxpandroidc7611652015-09-23 16:42:05 +05301496**
1497** Returns tNFC_STATUS
1498**
1499*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301500tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1501 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1502 uint16_t first_block;
1503 uint16_t num_block;
nxpandroidc7611652015-09-23 16:42:05 +05301504
nxf24591c1cbeab2018-02-21 17:32:26 +05301505 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301506
nxpandroid8f6d0532017-07-12 18:25:30 +05301507 first_block = offset / p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05301508
nxpandroid8f6d0532017-07-12 18:25:30 +05301509 /* more blocks, more efficent but more error rate */
nxpandroidc7611652015-09-23 16:42:05 +05301510
nxpandroid8f6d0532017-07-12 18:25:30 +05301511 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1512 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05301513
nxpandroid8f6d0532017-07-12 18:25:30 +05301514 if (num_block + first_block > p_i93->num_block)
1515 num_block = p_i93->num_block - first_block;
nxpandroidc7611652015-09-23 16:42:05 +05301516
nxpandroid8f6d0532017-07-12 18:25:30 +05301517 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
1518 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1519 ** - The max number of blocks is 32 and they are all located in the
1520 ** same sector.
1521 ** - The sector is 32 blocks of 4 bytes.
1522 */
1523 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1524 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1525 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1526 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
1527 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1528 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1529 num_block = I93_STM_MAX_BLOCKS_PER_READ;
nxpandroidc7611652015-09-23 16:42:05 +05301530
nxpandroid8f6d0532017-07-12 18:25:30 +05301531 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1532 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1533 num_block = I93_STM_BLOCKS_PER_SECTOR -
1534 (first_block % I93_STM_BLOCKS_PER_SECTOR);
nxpandroidc7611652015-09-23 16:42:05 +05301535 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301536 }
1537 }
nxpandroidc7611652015-09-23 16:42:05 +05301538
nxpandroid8f6d0532017-07-12 18:25:30 +05301539 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1540 } else {
1541 return rw_i93_send_cmd_read_single_block(first_block, false);
1542 }
nxpandroidc7611652015-09-23 16:42:05 +05301543}
1544
1545/*******************************************************************************
1546**
1547** Function rw_i93_get_next_block_sec
1548**
nxpandroid8f6d0532017-07-12 18:25:30 +05301549** Description Get as many security of blocks as possible from
1550** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
nxpandroidc7611652015-09-23 16:42:05 +05301551**
1552** Returns tNFC_STATUS
1553**
1554*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301555tNFC_STATUS rw_i93_get_next_block_sec(void) {
1556 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1557 uint16_t num_blocks;
nxpandroidc7611652015-09-23 16:42:05 +05301558
nxf24591c1cbeab2018-02-21 17:32:26 +05301559 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301560
nxpandroid8f6d0532017-07-12 18:25:30 +05301561 if (p_i93->num_block <= p_i93->rw_offset) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301562 LOG(ERROR) << StringPrintf(
1563 "rw_offset(0x%x) must be less than num_block(0x%x)", p_i93->rw_offset,
1564 p_i93->num_block);
nxpandroid8f6d0532017-07-12 18:25:30 +05301565 return NFC_STATUS_FAILED;
1566 }
nxpandroidc7611652015-09-23 16:42:05 +05301567
nxpandroid8f6d0532017-07-12 18:25:30 +05301568 num_blocks = p_i93->num_block - p_i93->rw_offset;
nxpandroidc7611652015-09-23 16:42:05 +05301569
nxpandroid8f6d0532017-07-12 18:25:30 +05301570 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1571 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +05301572
nxf24591c1cbeab2018-02-21 17:32:26 +05301573 DLOG_IF(INFO, nfc_debug_enabled)
1574 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
nxpandroid8f6d0532017-07-12 18:25:30 +05301575 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
nxpandroidc7611652015-09-23 16:42:05 +05301576}
1577
1578/*******************************************************************************
1579**
1580** Function rw_i93_sm_detect_ndef
1581**
1582** Description Process NDEF detection procedure
1583**
1584** 1. Get UID if not having yet
1585** 2. Get System Info if not having yet
1586** 3. Read first block for CC
1587** 4. Search NDEF Type and length
nxpandroid8f6d0532017-07-12 18:25:30 +05301588** 5. Get block status to get max NDEF size and read-only
1589** status
nxpandroidc7611652015-09-23 16:42:05 +05301590**
1591** Returns void
1592**
1593*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301594void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301595 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
nxpandroid8f6d0532017-07-12 18:25:30 +05301596 uint8_t flags, u8 = 0, cc[4];
1597 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1598 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1599 tRW_DATA rw_data;
1600 tNFC_STATUS status = NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301601
nxf24591c1cbeab2018-02-21 17:32:26 +05301602 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1603 "sub_state:%s (0x%x)",
1604 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301605
nxpandroid8f6d0532017-07-12 18:25:30 +05301606 STREAM_TO_UINT8(flags, p);
1607 length--;
nxpandroidc7611652015-09-23 16:42:05 +05301608
nxpandroid8f6d0532017-07-12 18:25:30 +05301609 if (flags & I93_FLAG_ERROR_DETECTED) {
1610 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1611 /* getting system info with protocol extension flag */
1612 /* This STM tag supports more than 2040 bytes */
1613 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1614 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301615 DLOG_IF(INFO, nfc_debug_enabled)
1616 << StringPrintf("Got error flags (0x%02x)", flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05301617 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05301618 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301619 return;
1620 }
nxpandroidc7611652015-09-23 16:42:05 +05301621
nxpandroid8f6d0532017-07-12 18:25:30 +05301622 switch (p_i93->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301623 case RW_I93_SUBSTATE_WAIT_UID:
1624
nxpandroid8f6d0532017-07-12 18:25:30 +05301625 STREAM_TO_UINT8(u8, p); /* DSFID */
1626 p_uid = p_i93->uid;
1627 STREAM_TO_ARRAY8(p_uid, p);
nxpandroidc7611652015-09-23 16:42:05 +05301628
nxpandroid8f6d0532017-07-12 18:25:30 +05301629 if (u8 != I93_DFS_UNSUPPORTED) {
1630 /* if Data Storage Format is unknown */
nxf24591c1cbeab2018-02-21 17:32:26 +05301631 DLOG_IF(INFO, nfc_debug_enabled)
1632 << StringPrintf("Got unknown DSFID (0x%02x)", u8);
nxpandroid8f6d0532017-07-12 18:25:30 +05301633 rw_i93_handle_error(NFC_STATUS_FAILED);
1634 } else {
1635 /* get system information to get memory size */
1636 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
1637 NFC_STATUS_OK) {
1638 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1639 } else {
1640 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05301641 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301642 }
1643 break;
nxpandroidc7611652015-09-23 16:42:05 +05301644
1645 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1646
nxpandroid8f6d0532017-07-12 18:25:30 +05301647 p_i93->block_size = 0;
1648 p_i93->num_block = 0;
nxpandroidc7611652015-09-23 16:42:05 +05301649
nxpandroid8f6d0532017-07-12 18:25:30 +05301650 if (!rw_i93_process_sys_info(p)) {
1651 /* retrying with protocol extension flag */
nxpandroidc7611652015-09-23 16:42:05 +05301652 break;
nxpandroid8f6d0532017-07-12 18:25:30 +05301653 }
1654
1655 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301656 DLOG_IF(INFO, nfc_debug_enabled)
1657 << StringPrintf("Unable to get tag memory size");
nxpandroid8f6d0532017-07-12 18:25:30 +05301658 rw_i93_handle_error(status);
1659 } else {
1660 /* read CC in the first block */
1661 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1662 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1663 } else {
1664 rw_i93_handle_error(NFC_STATUS_FAILED);
1665 }
1666 }
1667 break;
nxpandroidc7611652015-09-23 16:42:05 +05301668
1669 case RW_I93_SUBSTATE_WAIT_CC:
1670
nxpandroid8f6d0532017-07-12 18:25:30 +05301671 /* assume block size is more than 4 */
1672 STREAM_TO_ARRAY(cc, p, 4);
nxpandroidc7611652015-09-23 16:42:05 +05301673
nxpandroid8f6d0532017-07-12 18:25:30 +05301674 status = NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301675
nxpandroid8f6d0532017-07-12 18:25:30 +05301676 /*
1677 ** Capability Container (CC)
1678 **
1679 ** CC[0] : magic number (0xE1)
1680 ** CC[1] : Bit 7-6:Major version number
1681 ** : Bit 5-4:Minor version number
1682 ** : Bit 3-2:Read access condition (00b: read access granted
1683 ** without any security)
1684 ** : Bit 1-0:Write access condition (00b: write access granted
1685 ** without any security)
1686 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
1687 ** 0xFF if more than 2040bytes]
1688 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1689 ** : Bit 1:Inventory page read is supported [NXP]
1690 ** : Bit 2:More than 2040 bytes are supported [STM]
1691 */
nxpandroidc7611652015-09-23 16:42:05 +05301692
nxf24591c1cbeab2018-02-21 17:32:26 +05301693 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1694 "cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
1695 DLOG_IF(INFO, nfc_debug_enabled)
1696 << StringPrintf("Total blocks:0x%04X, Block size:0x%02X",
1697 p_i93->num_block, p_i93->block_size);
nxpandroidc7611652015-09-23 16:42:05 +05301698
nxf24591c1cbeab2018-02-21 17:32:26 +05301699 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1700 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301701 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1702 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1703 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1704 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1705 /* read-only or password required to write */
1706 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1707 }
1708 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
1709 /* tag supports read multi blocks command */
1710 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1711 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301712 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1713 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1714 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301715 status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301716 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301717 }
nxpandroidc7611652015-09-23 16:42:05 +05301718
nxpandroid8f6d0532017-07-12 18:25:30 +05301719 if (status == NFC_STATUS_OK) {
1720 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1721 */
1722 if (cc[2] != 0)
1723 p_i93->rw_offset = 4;
nxpandroidc7611652015-09-23 16:42:05 +05301724 else
nxpandroid8f6d0532017-07-12 18:25:30 +05301725 p_i93->rw_offset = 8;
1726
1727 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1728 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1729 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1730 } else {
1731 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05301732 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301733 } else {
1734 rw_i93_handle_error(NFC_STATUS_FAILED);
1735 }
1736 break;
nxpandroidc7611652015-09-23 16:42:05 +05301737
1738 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1739
nxpandroid8f6d0532017-07-12 18:25:30 +05301740 /* search TLV within read blocks */
1741 for (xx = 0; xx < length; xx++) {
1742 /* if looking for type */
1743 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1744 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1745 continue;
1746 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1747 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1748 /* store found type and get length field */
1749 p_i93->tlv_type = *(p + xx);
1750 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
nxpandroidc7611652015-09-23 16:42:05 +05301751
nxpandroid8f6d0532017-07-12 18:25:30 +05301752 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1753 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1754 /* no NDEF TLV found */
1755 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1756 break;
1757 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301758 DLOG_IF(INFO, nfc_debug_enabled)
1759 << StringPrintf("Invalid type: 0x%02x", *(p + xx));
nxpandroid8f6d0532017-07-12 18:25:30 +05301760 rw_i93_handle_error(NFC_STATUS_FAILED);
1761 return;
1762 }
1763 } else if (p_i93->tlv_detect_state ==
1764 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
1765 /* if 3 bytes length field */
1766 if (*(p + xx) == 0xFF) {
1767 /* need 2 more bytes for length field */
1768 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1769 } else {
1770 p_i93->tlv_length = *(p + xx);
1771 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1772
1773 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1774 p_i93->ndef_tlv_last_offset =
1775 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1776 break;
nxpandroidc7611652015-09-23 16:42:05 +05301777 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301778 }
1779 } else if (p_i93->tlv_detect_state ==
1780 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
1781 /* the second byte of 3 bytes length field */
1782 p_i93->tlv_length = *(p + xx);
1783 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1784 } else if (p_i93->tlv_detect_state ==
1785 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
1786 /* the last byte of 3 bytes length field */
1787 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
1788 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
nxpandroidc7611652015-09-23 16:42:05 +05301789
nxpandroid8f6d0532017-07-12 18:25:30 +05301790 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1791 p_i93->ndef_tlv_last_offset =
1792 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1793 break;
1794 }
1795 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
1796 /* this is other than NDEF TLV */
1797 if (p_i93->tlv_length <= length - xx) {
1798 /* skip value field */
1799 xx += (uint8_t)p_i93->tlv_length;
1800 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1801 } else {
nxpandroidc7611652015-09-23 16:42:05 +05301802 /* read more data */
nxpandroid8f6d0532017-07-12 18:25:30 +05301803 p_i93->tlv_length -= (length - xx);
1804 break;
1805 }
nxpandroidc7611652015-09-23 16:42:05 +05301806 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301807 }
1808
1809 /* found NDEF TLV and read length field */
1810 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
1811 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
1812 p_i93->ndef_length = p_i93->tlv_length;
1813
1814 /* get lock status to see if read-only */
1815 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1816 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1817 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1818 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1819 /* these doesn't support GetMultiBlockSecurityStatus */
1820
1821 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
1822 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
1823
1824 /* read block to get lock status */
1825 rw_i93_send_cmd_read_single_block(first_block, true);
1826 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1827 } else {
1828 /* block offset for read-only check */
1829 p_i93->rw_offset = 0;
1830
1831 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
1832 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1833 } else {
1834 rw_i93_handle_error(NFC_STATUS_FAILED);
1835 }
1836 }
1837 } else {
1838 /* read more data */
1839 p_i93->rw_offset += length;
1840
1841 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
1842 rw_i93_handle_error(NFC_STATUS_FAILED);
1843 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1844 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1845 } else {
1846 rw_i93_handle_error(NFC_STATUS_FAILED);
1847 }
1848 }
1849 break;
nxpandroidc7611652015-09-23 16:42:05 +05301850
1851 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1852
nxpandroid8f6d0532017-07-12 18:25:30 +05301853 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1854 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1855 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1856 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1857 /* these doesn't support GetMultiBlockSecurityStatus */
nxpandroidc7611652015-09-23 16:42:05 +05301858
nxpandroid8f6d0532017-07-12 18:25:30 +05301859 block = (p_i93->rw_offset / p_i93->block_size);
1860 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
nxpandroidc7611652015-09-23 16:42:05 +05301861
nxpandroid8f6d0532017-07-12 18:25:30 +05301862 if ((*p) & I93_BLOCK_LOCKED) {
1863 if (block <= last_block) {
1864 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1865 }
1866 } else {
1867 /* if we need to check more user blocks */
1868 if (block + 1 < p_i93->num_block) {
1869 p_i93->rw_offset += p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05301870
nxpandroid8f6d0532017-07-12 18:25:30 +05301871 /* read block to get lock status */
1872 rw_i93_send_cmd_read_single_block(
1873 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
1874 break;
1875 }
nxpandroidc7611652015-09-23 16:42:05 +05301876 }
1877
nxpandroid8f6d0532017-07-12 18:25:30 +05301878 p_i93->max_ndef_length =
1879 p_i93->ndef_length
1880 /* add available bytes including the last block of NDEF TLV */
nxf24591c1cbeab2018-02-21 17:32:26 +05301881 + (p_i93->block_size * (block - last_block) + 1) -
nxpandroid8f6d0532017-07-12 18:25:30 +05301882 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1883 } else {
1884 if (p_i93->rw_offset == 0) {
1885 p_i93->max_ndef_length =
1886 p_i93->ndef_length
1887 /* add available bytes in the last block of NDEF TLV */
nxf24591c1cbeab2018-02-21 17:32:26 +05301888 + p_i93->block_size -
nxpandroid8f6d0532017-07-12 18:25:30 +05301889 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1890
1891 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1892 } else {
1893 first_block = 0;
nxpandroidc7611652015-09-23 16:42:05 +05301894 }
1895
nxpandroid8f6d0532017-07-12 18:25:30 +05301896 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1897 num_blocks = length;
nxpandroidc7611652015-09-23 16:42:05 +05301898
nxpandroid8f6d0532017-07-12 18:25:30 +05301899 for (block = first_block; block < num_blocks; block++) {
1900 /* if any block of NDEF TLV is locked */
1901 if ((block + p_i93->rw_offset) <= last_block) {
1902 if (*(p + block) & I93_BLOCK_LOCKED) {
1903 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1904 break;
1905 }
1906 } else {
1907 if (*(p + block) & I93_BLOCK_LOCKED) {
1908 /* no more consecutive unlocked block */
1909 break;
1910 } else {
1911 /* add block size if not locked */
1912 p_i93->max_ndef_length += p_i93->block_size;
1913 }
1914 }
nxpandroidc7611652015-09-23 16:42:05 +05301915 }
1916
nxpandroid8f6d0532017-07-12 18:25:30 +05301917 /* update next security of block to check */
1918 p_i93->rw_offset += num_blocks;
nxpandroidc7611652015-09-23 16:42:05 +05301919
nxpandroid8f6d0532017-07-12 18:25:30 +05301920 /* if need to check more */
1921 if (p_i93->num_block > p_i93->rw_offset) {
1922 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
1923 rw_i93_handle_error(NFC_STATUS_FAILED);
1924 }
1925 break;
1926 }
1927 }
nxpandroidc7611652015-09-23 16:42:05 +05301928
nxpandroid8f6d0532017-07-12 18:25:30 +05301929 /* check if need to adjust max NDEF length */
1930 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
1931 /* 3 bytes length field must be used */
1932 p_i93->max_ndef_length -= 2;
1933 }
1934
1935 rw_data.ndef.status = NFC_STATUS_OK;
nxf24591c1cbeab2018-02-21 17:32:26 +05301936 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
nxpandroid8f6d0532017-07-12 18:25:30 +05301937 rw_data.ndef.flags = 0;
1938 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
1939 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
1940 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
1941 rw_data.ndef.cur_size = p_i93->ndef_length;
1942
1943 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
1944 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1945 rw_data.ndef.max_size = p_i93->ndef_length;
1946 } else {
1947 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
1948 rw_data.ndef.max_size = p_i93->max_ndef_length;
1949 }
1950
1951 p_i93->state = RW_I93_STATE_IDLE;
1952 p_i93->sent_cmd = 0;
1953
nxf24591c1cbeab2018-02-21 17:32:26 +05301954 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1955 "NDEF cur_size(%d),max_size (%d), flags (0x%x)",
1956 rw_data.ndef.cur_size, rw_data.ndef.max_size, rw_data.ndef.flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05301957
1958 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
1959 break;
nxpandroidc7611652015-09-23 16:42:05 +05301960
1961 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05301962 break;
1963 }
nxpandroidc7611652015-09-23 16:42:05 +05301964}
1965
1966/*******************************************************************************
1967**
1968** Function rw_i93_sm_read_ndef
1969**
1970** Description Process NDEF read procedure
1971**
1972** Returns void
1973**
1974*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301975void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301976 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
nxpandroid8f6d0532017-07-12 18:25:30 +05301977 uint8_t flags;
nxf24591c1cbeab2018-02-21 17:32:26 +05301978 uint16_t offset, length = p_resp->len;
nxpandroid8f6d0532017-07-12 18:25:30 +05301979 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1980 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301981
nxf24591c1cbeab2018-02-21 17:32:26 +05301982 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301983
nxpandroid8f6d0532017-07-12 18:25:30 +05301984 STREAM_TO_UINT8(flags, p);
1985 length--;
nxpandroidc7611652015-09-23 16:42:05 +05301986
nxpandroid8f6d0532017-07-12 18:25:30 +05301987 if (flags & I93_FLAG_ERROR_DETECTED) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301988 DLOG_IF(INFO, nfc_debug_enabled)
1989 << StringPrintf("Got error flags (0x%02x)", flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05301990 rw_i93_handle_error(NFC_STATUS_FAILED);
1991 return;
1992 }
1993
1994 /* if this is the first block */
1995 if (p_i93->rw_length == 0) {
1996 /* get start of NDEF in the first block */
1997 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
1998
1999 if (p_i93->ndef_length < 0xFF) {
2000 offset += 2;
2001 } else {
2002 offset += 4;
nxpandroidc7611652015-09-23 16:42:05 +05302003 }
2004
nxpandroid8f6d0532017-07-12 18:25:30 +05302005 /* adjust offset if read more blocks because the first block doesn't have
2006 * NDEF */
2007 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
2008 } else {
2009 offset = 0;
2010 }
nxpandroidc7611652015-09-23 16:42:05 +05302011
nxpandroid8f6d0532017-07-12 18:25:30 +05302012 /* if read enough data to skip type and length field for the beginning */
2013 if (offset < length) {
2014 offset++; /* flags */
2015 p_resp->offset += offset;
2016 p_resp->len -= offset;
nxpandroidc7611652015-09-23 16:42:05 +05302017
nxpandroid8f6d0532017-07-12 18:25:30 +05302018 rw_data.data.status = NFC_STATUS_OK;
2019 rw_data.data.p_data = p_resp;
2020
2021 p_i93->rw_length += p_resp->len;
2022 } else {
2023 /* in case of no Ndef data included */
2024 p_resp->len = 0;
2025 }
2026
2027 /* if read all of NDEF data */
2028 if (p_i93->rw_length >= p_i93->ndef_length) {
2029 /* remove extra btyes in the last block */
2030 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2031
2032 p_i93->state = RW_I93_STATE_IDLE;
2033 p_i93->sent_cmd = 0;
2034
nxf24591c1cbeab2018-02-21 17:32:26 +05302035 DLOG_IF(INFO, nfc_debug_enabled)
2036 << StringPrintf("NDEF read complete read (%d)/total (%d)", p_resp->len,
2037 p_i93->ndef_length);
nxpandroid8f6d0532017-07-12 18:25:30 +05302038
2039 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2040 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302041 DLOG_IF(INFO, nfc_debug_enabled)
2042 << StringPrintf("NDEF read segment read (%d)/total (%d)", p_resp->len,
2043 p_i93->ndef_length);
nxpandroid8f6d0532017-07-12 18:25:30 +05302044
2045 if (p_resp->len > 0) {
2046 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05302047 }
2048
nxpandroid8f6d0532017-07-12 18:25:30 +05302049 /* this will make read data from next block */
2050 p_i93->rw_offset += length;
nxpandroidc7611652015-09-23 16:42:05 +05302051
nxpandroid8f6d0532017-07-12 18:25:30 +05302052 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2053 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302054 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302055 }
nxpandroidc7611652015-09-23 16:42:05 +05302056}
2057
2058/*******************************************************************************
2059**
2060** Function rw_i93_sm_update_ndef
2061**
2062** Description Process NDEF update procedure
2063**
2064** 1. Set length field to zero
2065** 2. Write NDEF and Terminator TLV
2066** 3. Set length field to NDEF length
2067**
2068** Returns void
2069**
2070*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302071void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
2072 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2073 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2074 uint16_t length = p_resp->len, block_number;
2075 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2076 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05302077
nxf24591c1cbeab2018-02-21 17:32:26 +05302078 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2079 "sub_state:%s (0x%x)",
2080 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05302081
nxpandroid8f6d0532017-07-12 18:25:30 +05302082 STREAM_TO_UINT8(flags, p);
2083 length--;
nxpandroidc7611652015-09-23 16:42:05 +05302084
nxpandroid8f6d0532017-07-12 18:25:30 +05302085 if (flags & I93_FLAG_ERROR_DETECTED) {
2086 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2087 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2088 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2089 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2090 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2091 /* ignore error */
2092 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302093 DLOG_IF(INFO, nfc_debug_enabled)
2094 << StringPrintf("Got error flags (0x%02x)", flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05302095 rw_i93_handle_error(NFC_STATUS_FAILED);
2096 return;
nxpandroidc7611652015-09-23 16:42:05 +05302097 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302098 }
nxpandroidc7611652015-09-23 16:42:05 +05302099
nxpandroid8f6d0532017-07-12 18:25:30 +05302100 switch (p_i93->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05302101 case RW_I93_SUBSTATE_RESET_LEN:
2102
nxpandroid8f6d0532017-07-12 18:25:30 +05302103 /* get offset of length field */
2104 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302105
nxpandroid8f6d0532017-07-12 18:25:30 +05302106 /* set length to zero */
2107 *(p + length_offset) = 0x00;
nxpandroidc7611652015-09-23 16:42:05 +05302108
nxpandroid8f6d0532017-07-12 18:25:30 +05302109 if (p_i93->ndef_length > 0) {
2110 /* if 3 bytes length field is needed */
2111 if (p_i93->ndef_length >= 0xFF) {
2112 xx = length_offset + 3;
2113 } else {
2114 xx = length_offset + 1;
nxpandroidc7611652015-09-23 16:42:05 +05302115 }
2116
nxpandroid8f6d0532017-07-12 18:25:30 +05302117 /* write the first part of NDEF in the same block */
2118 for (; xx < p_i93->block_size; xx++) {
2119 if (p_i93->rw_length < p_i93->ndef_length) {
2120 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2121 } else {
2122 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2123 }
2124 }
2125 }
nxpandroidc7611652015-09-23 16:42:05 +05302126
nxpandroid8f6d0532017-07-12 18:25:30 +05302127 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2128
2129 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2130 NFC_STATUS_OK) {
2131 /* update next writing offset */
2132 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2133 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2134 } else {
2135 rw_i93_handle_error(NFC_STATUS_FAILED);
2136 }
2137 break;
nxpandroidc7611652015-09-23 16:42:05 +05302138
2139 case RW_I93_SUBSTATE_WRITE_NDEF:
2140
nxpandroid8f6d0532017-07-12 18:25:30 +05302141 /* if it's not the end of tag memory */
2142 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
2143 block_number = p_i93->rw_offset / p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302144
nxpandroid8f6d0532017-07-12 18:25:30 +05302145 /* if we have more data to write */
2146 if (p_i93->rw_length < p_i93->ndef_length) {
2147 p = p_i93->p_update_data + p_i93->rw_length;
nxpandroidc7611652015-09-23 16:42:05 +05302148
nxpandroid8f6d0532017-07-12 18:25:30 +05302149 p_i93->rw_offset += p_i93->block_size;
2150 p_i93->rw_length += p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302151
nxpandroid8f6d0532017-07-12 18:25:30 +05302152 /* if this is the last block of NDEF TLV */
2153 if (p_i93->rw_length > p_i93->ndef_length) {
2154 /* length of NDEF TLV in the block */
2155 xx = (uint8_t)(p_i93->block_size -
2156 (p_i93->rw_length - p_i93->ndef_length));
nxpandroidc7611652015-09-23 16:42:05 +05302157
nxpandroid8f6d0532017-07-12 18:25:30 +05302158 /* set NULL TLV in the unused part of block */
2159 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2160 memcpy(buff, p, xx);
2161 p = buff;
nxpandroidc7611652015-09-23 16:42:05 +05302162
nxpandroid8f6d0532017-07-12 18:25:30 +05302163 /* if it's the end of tag memory */
2164 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2165 (xx < p_i93->block_size)) {
2166 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
nxpandroidc7611652015-09-23 16:42:05 +05302167 }
nxpandroidc7611652015-09-23 16:42:05 +05302168
nxpandroid8f6d0532017-07-12 18:25:30 +05302169 p_i93->ndef_tlv_last_offset =
2170 p_i93->rw_offset - p_i93->block_size + xx - 1;
2171 }
nxpandroidc7611652015-09-23 16:42:05 +05302172
nxpandroid8f6d0532017-07-12 18:25:30 +05302173 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2174 NFC_STATUS_OK) {
2175 rw_i93_handle_error(NFC_STATUS_FAILED);
2176 }
2177 } else {
2178 /* if this is the very next block of NDEF TLV */
2179 if (block_number ==
2180 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2181 p_i93->rw_offset += p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302182
nxpandroid8f6d0532017-07-12 18:25:30 +05302183 /* write Terminator TLV and NULL TLV */
2184 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2185 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2186 p = buff;
nxpandroidc7611652015-09-23 16:42:05 +05302187
nxpandroid8f6d0532017-07-12 18:25:30 +05302188 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2189 NFC_STATUS_OK) {
2190 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302191 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302192 } else {
2193 /* finished writing NDEF and Terminator TLV */
2194 /* read length field to update length */
2195 block_number =
2196 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2197
2198 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2199 NFC_STATUS_OK) {
2200 /* set offset to length field */
2201 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2202
2203 /* get size of length field */
2204 if (p_i93->ndef_length >= 0xFF) {
2205 p_i93->rw_length = 3;
2206 } else if (p_i93->ndef_length > 0) {
2207 p_i93->rw_length = 1;
2208 } else {
2209 p_i93->rw_length = 0;
2210 }
2211
2212 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2213 } else {
2214 rw_i93_handle_error(NFC_STATUS_FAILED);
2215 }
2216 }
nxpandroidc7611652015-09-23 16:42:05 +05302217 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302218 } else {
2219 /* if we have no more data to write */
2220 if (p_i93->rw_length >= p_i93->ndef_length) {
2221 /* finished writing NDEF and Terminator TLV */
2222 /* read length field to update length */
2223 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302224
nxpandroid8f6d0532017-07-12 18:25:30 +05302225 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2226 NFC_STATUS_OK) {
2227 /* set offset to length field */
2228 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
nxpandroidc7611652015-09-23 16:42:05 +05302229
nxpandroid8f6d0532017-07-12 18:25:30 +05302230 /* get size of length field */
2231 if (p_i93->ndef_length >= 0xFF) {
2232 p_i93->rw_length = 3;
2233 } else if (p_i93->ndef_length > 0) {
2234 p_i93->rw_length = 1;
2235 } else {
2236 p_i93->rw_length = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302237 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302238
2239 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2240 break;
2241 }
nxpandroidc7611652015-09-23 16:42:05 +05302242 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302243 rw_i93_handle_error(NFC_STATUS_FAILED);
2244 }
2245 break;
nxpandroidc7611652015-09-23 16:42:05 +05302246
2247 case RW_I93_SUBSTATE_UPDATE_LEN:
2248
nxpandroid8f6d0532017-07-12 18:25:30 +05302249 /* if we have more length field to write */
2250 if (p_i93->rw_length > 0) {
2251 /* if we got ack for writing, read next block to update rest of length
2252 * field */
2253 if (length == 0) {
2254 block_number = p_i93->rw_offset / p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302255
nxpandroid8f6d0532017-07-12 18:25:30 +05302256 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2257 NFC_STATUS_OK) {
2258 rw_i93_handle_error(NFC_STATUS_FAILED);
2259 }
2260 } else {
2261 length_offset = p_i93->rw_offset % p_i93->block_size;
nxpandroidc7611652015-09-23 16:42:05 +05302262
nxpandroid8f6d0532017-07-12 18:25:30 +05302263 /* update length field within the read block */
2264 for (xx = length_offset; xx < p_i93->block_size; xx++) {
2265 if (p_i93->rw_length == 3)
2266 *(p + xx) = 0xFF;
2267 else if (p_i93->rw_length == 2)
2268 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2269 else if (p_i93->rw_length == 1)
2270 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
nxpandroidc7611652015-09-23 16:42:05 +05302271
nxpandroid8f6d0532017-07-12 18:25:30 +05302272 p_i93->rw_length--;
2273 if (p_i93->rw_length == 0) break;
2274 }
nxpandroidc7611652015-09-23 16:42:05 +05302275
nxpandroid8f6d0532017-07-12 18:25:30 +05302276 block_number = (p_i93->rw_offset / p_i93->block_size);
nxpandroidc7611652015-09-23 16:42:05 +05302277
nxpandroid8f6d0532017-07-12 18:25:30 +05302278 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2279 NFC_STATUS_OK) {
2280 /* set offset to the beginning of next block */
2281 p_i93->rw_offset +=
2282 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2283 } else {
2284 rw_i93_handle_error(NFC_STATUS_FAILED);
2285 }
nxpandroidc7611652015-09-23 16:42:05 +05302286 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302287 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302288 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2289 "NDEF update complete, %d bytes, (%d-%d)", p_i93->ndef_length,
2290 p_i93->ndef_tlv_start_offset, p_i93->ndef_tlv_last_offset);
nxpandroidc7611652015-09-23 16:42:05 +05302291
nxpandroid8f6d0532017-07-12 18:25:30 +05302292 p_i93->state = RW_I93_STATE_IDLE;
2293 p_i93->sent_cmd = 0;
2294 p_i93->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05302295
nxpandroid8f6d0532017-07-12 18:25:30 +05302296 rw_data.status = NFC_STATUS_OK;
2297 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2298 }
2299 break;
nxpandroidc7611652015-09-23 16:42:05 +05302300
2301 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302302 break;
2303 }
nxpandroidc7611652015-09-23 16:42:05 +05302304}
2305
2306/*******************************************************************************
2307**
2308** Function rw_i93_sm_format
2309**
2310** Description Process format procedure
2311**
2312** 1. Get UID
2313** 2. Get sys info for memory size (reset AFI/DSFID)
2314** 3. Get block status to get read-only status
2315** 4. Write CC and empty NDEF
2316**
2317** Returns void
2318**
2319*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302320void rw_i93_sm_format(NFC_HDR* p_resp) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302321 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
nxpandroid8f6d0532017-07-12 18:25:30 +05302322 uint8_t flags;
2323 uint16_t length = p_resp->len, xx, block_number;
2324 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2325 tRW_DATA rw_data;
2326 tNFC_STATUS status = NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302327
nxf24591c1cbeab2018-02-21 17:32:26 +05302328 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2329 "sub_state:%s (0x%x)",
2330 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05302331
nxpandroid8f6d0532017-07-12 18:25:30 +05302332 STREAM_TO_UINT8(flags, p);
2333 length--;
nxpandroidc7611652015-09-23 16:42:05 +05302334
nxpandroid8f6d0532017-07-12 18:25:30 +05302335 if (flags & I93_FLAG_ERROR_DETECTED) {
2336 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2337 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2338 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2339 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2340 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2341 /* ignore error */
2342 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2343 /* getting system info with protocol extension flag */
2344 /* This STM tag supports more than 2040 bytes */
2345 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2346 return;
2347 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302348 DLOG_IF(INFO, nfc_debug_enabled)
2349 << StringPrintf("Got error flags (0x%02x)", flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05302350 rw_i93_handle_error(NFC_STATUS_FAILED);
2351 return;
nxpandroidc7611652015-09-23 16:42:05 +05302352 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302353 }
nxpandroidc7611652015-09-23 16:42:05 +05302354
nxpandroid8f6d0532017-07-12 18:25:30 +05302355 switch (p_i93->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05302356 case RW_I93_SUBSTATE_WAIT_UID:
2357
nxpandroid8f6d0532017-07-12 18:25:30 +05302358 p++; /* skip DSFID */
2359 p_uid = p_i93->uid;
2360 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
nxpandroidc7611652015-09-23 16:42:05 +05302361
nxpandroid8f6d0532017-07-12 18:25:30 +05302362 /* get system information to get memory size */
2363 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
2364 NFC_STATUS_OK) {
2365 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2366 } else {
2367 rw_i93_handle_error(NFC_STATUS_FAILED);
2368 }
2369 break;
nxpandroidc7611652015-09-23 16:42:05 +05302370
2371 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2372
nxpandroid8f6d0532017-07-12 18:25:30 +05302373 p_i93->block_size = 0;
2374 p_i93->num_block = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302375
nxpandroid8f6d0532017-07-12 18:25:30 +05302376 if (!rw_i93_process_sys_info(p)) {
2377 /* retrying with protocol extension flag */
nxpandroidc7611652015-09-23 16:42:05 +05302378 break;
nxpandroid8f6d0532017-07-12 18:25:30 +05302379 }
2380
2381 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2382 /* DSFID, if any DSFID then reset */
2383 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2384 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2385 }
2386 }
2387 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2388 /* AFI, reset to 0 */
2389 if (p_i93->afi != 0x00) {
2390 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2391 }
2392 }
2393
2394 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302395 DLOG_IF(INFO, nfc_debug_enabled)
2396 << StringPrintf("Unable to get tag memory size");
nxpandroid8f6d0532017-07-12 18:25:30 +05302397 rw_i93_handle_error(status);
2398 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2399 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2400 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2401 } else {
2402 rw_i93_handle_error(NFC_STATUS_FAILED);
2403 }
2404 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2405 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2406 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2407 } else {
2408 rw_i93_handle_error(NFC_STATUS_FAILED);
2409 }
2410 } else {
2411 /* get lock status to see if read-only */
2412 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2413 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2414 /* these doesn't support GetMultiBlockSecurityStatus */
2415
2416 rw_cb.tcb.i93.rw_offset = 0;
2417
2418 /* read blocks with option flag to get block security status */
2419 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2420 NFC_STATUS_OK) {
2421 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2422 } else {
2423 rw_i93_handle_error(NFC_STATUS_FAILED);
2424 }
2425 } else {
2426 /* block offset for read-only check */
2427 p_i93->rw_offset = 0;
2428
2429 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2430 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2431 } else {
2432 rw_i93_handle_error(NFC_STATUS_FAILED);
2433 }
2434 }
2435 }
2436
2437 break;
nxpandroidc7611652015-09-23 16:42:05 +05302438
2439 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2440
nxpandroid8f6d0532017-07-12 18:25:30 +05302441 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2442 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2443 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2444 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2445 }
nxpandroidc7611652015-09-23 16:42:05 +05302446
nxpandroid8f6d0532017-07-12 18:25:30 +05302447 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2448 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2449 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2450 } else {
2451 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302452 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302453 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2454 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2455 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2456 } else {
2457 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302458 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302459 } else {
2460 /* get lock status to see if read-only */
2461 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2462 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2463 /* these doesn't support GetMultiBlockSecurityStatus */
nxpandroidc7611652015-09-23 16:42:05 +05302464
nxpandroid8f6d0532017-07-12 18:25:30 +05302465 rw_cb.tcb.i93.rw_offset = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302466
nxpandroid8f6d0532017-07-12 18:25:30 +05302467 /* read blocks with option flag to get block security status */
2468 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2469 NFC_STATUS_OK) {
2470 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2471 } else {
2472 rw_i93_handle_error(NFC_STATUS_FAILED);
2473 }
2474 } else {
2475 /* block offset for read-only check */
2476 p_i93->rw_offset = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302477
nxpandroid8f6d0532017-07-12 18:25:30 +05302478 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2479 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2480 } else {
2481 rw_i93_handle_error(NFC_STATUS_FAILED);
2482 }
nxpandroidc7611652015-09-23 16:42:05 +05302483 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302484 }
2485 break;
nxpandroidc7611652015-09-23 16:42:05 +05302486
2487 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2488
nxpandroid8f6d0532017-07-12 18:25:30 +05302489 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2490 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2491 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2492 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2493 if ((*p) & I93_BLOCK_LOCKED) {
2494 rw_i93_handle_error(NFC_STATUS_FAILED);
2495 break;
nxpandroidc7611652015-09-23 16:42:05 +05302496 }
2497
nxpandroid8f6d0532017-07-12 18:25:30 +05302498 /* if we checked all of user blocks */
2499 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2500 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2501 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2502 /* read the block which has AFI */
2503 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2504 rw_i93_send_cmd_read_single_block(
2505 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
nxpandroidc7611652015-09-23 16:42:05 +05302506 break;
nxpandroid8f6d0532017-07-12 18:25:30 +05302507 }
2508 } else if (p_i93->rw_offset ==
2509 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2510 /* no block is locked */
2511 } else {
2512 p_i93->rw_offset += p_i93->block_size;
2513 rw_i93_send_cmd_read_single_block(
2514 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2515 break;
2516 }
2517 } else {
2518 /* if any block is locked, we cannot format it */
2519 for (xx = 0; xx < length; xx++) {
2520 if (*(p + xx) & I93_BLOCK_LOCKED) {
2521 rw_i93_handle_error(NFC_STATUS_FAILED);
2522 break;
2523 }
nxpandroidc7611652015-09-23 16:42:05 +05302524 }
2525
nxpandroid8f6d0532017-07-12 18:25:30 +05302526 /* update block offset for read-only check */
2527 p_i93->rw_offset += length;
nxpandroidc7611652015-09-23 16:42:05 +05302528
nxpandroid8f6d0532017-07-12 18:25:30 +05302529 /* if need to get more lock status of blocks */
2530 if (p_i93->num_block > p_i93->rw_offset) {
2531 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2532 rw_i93_handle_error(NFC_STATUS_FAILED);
2533 }
2534 break;
nxpandroidc7611652015-09-23 16:42:05 +05302535 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302536 }
nxpandroidc7611652015-09-23 16:42:05 +05302537
nxpandroid8f6d0532017-07-12 18:25:30 +05302538 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2539 p_i93->p_update_data = (uint8_t*)GKI_getbuf(RW_I93_FORMAT_DATA_LEN);
nxpandroidc7611652015-09-23 16:42:05 +05302540
nxpandroid8f6d0532017-07-12 18:25:30 +05302541 if (!p_i93->p_update_data) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302542 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +05302543 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302544 break;
nxpandroid8f6d0532017-07-12 18:25:30 +05302545 }
2546
2547 p = p_i93->p_update_data;
2548
2549 /* Capability Container */
nxf24591c1cbeab2018-02-21 17:32:26 +05302550 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
nxpandroid8f6d0532017-07-12 18:25:30 +05302551 *(p++) = 0x40; /* version 1.0, read/write */
2552
2553 /* if memory size is less than 2048 bytes */
2554 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2555 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2556 8); /* memory size */
2557 else
2558 *(p++) = 0xFF;
2559
2560 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2561 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2562 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2563 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2564 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2565 else
2566 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2567 supported */
2568 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2569 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2570 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2571 supported */
2572 } else if ((p_i93->product_version ==
2573 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2574 (p_i93->product_version ==
2575 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2576 *(p++) = 0;
2577 } else {
2578 /* STM except LRIS2K, Broadcom supports read multi block command */
2579
2580 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2581 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2582 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2583 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2584 *(p++) = 0x00;
2585 else
2586 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2587 }
2588
2589 /* zero length NDEF and Terminator TLV */
2590 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2591 *(p++) = 0x00;
2592 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2593 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2594
2595 /* start from block 0 */
2596 p_i93->rw_offset = 0;
2597
2598 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2599 NFC_STATUS_OK) {
2600 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2601 p_i93->rw_offset += p_i93->block_size;
2602 } else {
2603 rw_i93_handle_error(NFC_STATUS_FAILED);
2604 }
2605 break;
nxpandroidc7611652015-09-23 16:42:05 +05302606
2607 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2608
nxpandroid8f6d0532017-07-12 18:25:30 +05302609 /* if we have more data to write */
2610 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2611 block_number = (p_i93->rw_offset / p_i93->block_size);
2612 p = p_i93->p_update_data + p_i93->rw_offset;
nxpandroidc7611652015-09-23 16:42:05 +05302613
nxpandroid8f6d0532017-07-12 18:25:30 +05302614 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2615 NFC_STATUS_OK) {
2616 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2617 p_i93->rw_offset += p_i93->block_size;
2618 } else {
2619 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302620 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302621 } else {
2622 GKI_freebuf(p_i93->p_update_data);
2623 p_i93->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05302624
nxpandroid8f6d0532017-07-12 18:25:30 +05302625 p_i93->state = RW_I93_STATE_IDLE;
2626 p_i93->sent_cmd = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302627
nxpandroid8f6d0532017-07-12 18:25:30 +05302628 rw_data.status = NFC_STATUS_OK;
2629 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2630 }
2631 break;
nxpandroidc7611652015-09-23 16:42:05 +05302632
2633 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302634 break;
2635 }
nxpandroidc7611652015-09-23 16:42:05 +05302636}
2637
2638/*******************************************************************************
2639**
2640** Function rw_i93_sm_set_read_only
2641**
2642** Description Process read-only procedure
2643**
2644** 1. Update CC as read-only
2645** 2. Lock all block of NDEF TLV
2646** 3. Lock block of CC
2647**
2648** Returns void
2649**
2650*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302651void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2652 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2653 uint8_t flags, block_number;
2654 uint16_t length = p_resp->len;
2655 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2656 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05302657
nxf24591c1cbeab2018-02-21 17:32:26 +05302658 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2659 "sub_state:%s (0x%x)",
2660 rw_i93_get_sub_state_name(p_i93->sub_state).c_str(), p_i93->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05302661
nxpandroid8f6d0532017-07-12 18:25:30 +05302662 STREAM_TO_UINT8(flags, p);
2663 length--;
nxpandroidc7611652015-09-23 16:42:05 +05302664
nxpandroid8f6d0532017-07-12 18:25:30 +05302665 if (flags & I93_FLAG_ERROR_DETECTED) {
2666 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2667 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2668 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2669 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2670 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2671 /* ignore error */
2672 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302673 DLOG_IF(INFO, nfc_debug_enabled)
2674 << StringPrintf("Got error flags (0x%02x)", flags);
nxpandroid8f6d0532017-07-12 18:25:30 +05302675 rw_i93_handle_error(NFC_STATUS_FAILED);
2676 return;
nxpandroidc7611652015-09-23 16:42:05 +05302677 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302678 }
nxpandroidc7611652015-09-23 16:42:05 +05302679
nxpandroid8f6d0532017-07-12 18:25:30 +05302680 switch (p_i93->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05302681 case RW_I93_SUBSTATE_WAIT_CC:
2682
nxpandroid8f6d0532017-07-12 18:25:30 +05302683 /* mark CC as read-only */
2684 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
nxpandroidc7611652015-09-23 16:42:05 +05302685
nxpandroid8f6d0532017-07-12 18:25:30 +05302686 if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
2687 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2688 } else {
2689 rw_i93_handle_error(NFC_STATUS_FAILED);
2690 }
2691 break;
nxpandroidc7611652015-09-23 16:42:05 +05302692
2693 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2694
nxpandroid8f6d0532017-07-12 18:25:30 +05302695 /* successfully write CC then lock all blocks of NDEF TLV */
2696 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2697 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
nxpandroidc7611652015-09-23 16:42:05 +05302698
nxpandroid8f6d0532017-07-12 18:25:30 +05302699 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2700 p_i93->rw_offset += p_i93->block_size;
2701 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2702 } else {
2703 rw_i93_handle_error(NFC_STATUS_FAILED);
2704 }
2705 break;
nxpandroidc7611652015-09-23 16:42:05 +05302706
2707 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2708
nxpandroid8f6d0532017-07-12 18:25:30 +05302709 /* if we need to lock more blocks */
2710 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
2711 /* get the next block of NDEF TLV */
2712 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
nxpandroidc7611652015-09-23 16:42:05 +05302713
nxpandroid8f6d0532017-07-12 18:25:30 +05302714 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2715 p_i93->rw_offset += p_i93->block_size;
2716 } else {
2717 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302718 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302719 }
2720 /* if the first block of NDEF TLV is different from block of CC */
2721 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
2722 /* lock block of CC */
2723 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
2724 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2725 } else {
2726 rw_i93_handle_error(NFC_STATUS_FAILED);
nxpandroidc7611652015-09-23 16:42:05 +05302727 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302728 } else {
2729 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2730 p_i93->state = RW_I93_STATE_IDLE;
2731 p_i93->sent_cmd = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302732
nxpandroid8f6d0532017-07-12 18:25:30 +05302733 rw_data.status = NFC_STATUS_OK;
2734 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2735 }
2736 break;
nxpandroidc7611652015-09-23 16:42:05 +05302737
2738 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2739
nxpandroid8f6d0532017-07-12 18:25:30 +05302740 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2741 p_i93->state = RW_I93_STATE_IDLE;
2742 p_i93->sent_cmd = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302743
nxpandroid8f6d0532017-07-12 18:25:30 +05302744 rw_data.status = NFC_STATUS_OK;
2745 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2746 break;
nxpandroidc7611652015-09-23 16:42:05 +05302747
2748 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05302749 break;
2750 }
nxpandroidc7611652015-09-23 16:42:05 +05302751}
2752
2753/*******************************************************************************
2754**
2755** Function rw_i93_handle_error
2756**
2757** Description notify error to application and clean up
2758**
2759** Returns none
2760**
2761*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302762void rw_i93_handle_error(tNFC_STATUS status) {
2763 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2764 tRW_DATA rw_data;
2765 tRW_EVENT event;
nxpandroidc7611652015-09-23 16:42:05 +05302766
nxf24591c1cbeab2018-02-21 17:32:26 +05302767 DLOG_IF(INFO, nfc_debug_enabled)
2768 << StringPrintf("status:0x%02X, state:0x%X", status, p_i93->state);
nxpandroidc7611652015-09-23 16:42:05 +05302769
nxpandroid8f6d0532017-07-12 18:25:30 +05302770 nfc_stop_quick_timer(&p_i93->timer);
nxpandroidc7611652015-09-23 16:42:05 +05302771
nxpandroid8f6d0532017-07-12 18:25:30 +05302772 if (rw_cb.p_cback) {
2773 rw_data.status = status;
nxpandroidc7611652015-09-23 16:42:05 +05302774
nxpandroid8f6d0532017-07-12 18:25:30 +05302775 switch (p_i93->state) {
2776 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2777 event = RW_I93_INTF_ERROR_EVT;
2778 break;
nxpandroidc7611652015-09-23 16:42:05 +05302779
nxpandroid8f6d0532017-07-12 18:25:30 +05302780 case RW_I93_STATE_BUSY:
2781 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
2782 /* There is no response to Stay Quiet command */
2783 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2784 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2785 rw_data.i93_cmd_cmpl.error_code = 0;
2786 event = RW_I93_CMD_CMPL_EVT;
2787 } else {
2788 event = RW_I93_INTF_ERROR_EVT;
nxpandroidc7611652015-09-23 16:42:05 +05302789 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302790 break;
nxpandroidc7611652015-09-23 16:42:05 +05302791
nxpandroid8f6d0532017-07-12 18:25:30 +05302792 case RW_I93_STATE_DETECT_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302793 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
nxpandroid8f6d0532017-07-12 18:25:30 +05302794 rw_data.ndef.cur_size = 0;
2795 rw_data.ndef.max_size = 0;
2796 rw_data.ndef.flags = 0;
2797 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2798 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2799 event = RW_I93_NDEF_DETECT_EVT;
2800 break;
nxpandroidc7611652015-09-23 16:42:05 +05302801
nxpandroid8f6d0532017-07-12 18:25:30 +05302802 case RW_I93_STATE_READ_NDEF:
2803 event = RW_I93_NDEF_READ_FAIL_EVT;
2804 break;
2805
2806 case RW_I93_STATE_UPDATE_NDEF:
2807 p_i93->p_update_data = NULL;
2808 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2809 break;
2810
2811 case RW_I93_STATE_FORMAT:
2812 if (p_i93->p_update_data) {
2813 GKI_freebuf(p_i93->p_update_data);
2814 p_i93->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05302815 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302816 event = RW_I93_FORMAT_CPLT_EVT;
2817 break;
2818
2819 case RW_I93_STATE_SET_READ_ONLY:
2820 event = RW_I93_SET_TAG_RO_EVT;
2821 break;
2822
2823 case RW_I93_STATE_PRESENCE_CHECK:
2824 event = RW_I93_PRESENCE_CHECK_EVT;
2825 break;
2826
2827 default:
2828 event = RW_I93_MAX_EVT;
2829 break;
nxpandroidc7611652015-09-23 16:42:05 +05302830 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302831
2832 p_i93->state = RW_I93_STATE_IDLE;
2833 p_i93->sent_cmd = 0;
2834
2835 if (event != RW_I93_MAX_EVT) {
2836 (*(rw_cb.p_cback))(event, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05302837 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302838 } else {
2839 p_i93->state = RW_I93_STATE_IDLE;
2840 }
nxpandroidc7611652015-09-23 16:42:05 +05302841}
2842
2843/*******************************************************************************
2844**
2845** Function rw_i93_process_timeout
2846**
2847** Description process timeout event
2848**
2849** Returns none
2850**
2851*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302852void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2853 NFC_HDR* p_buf;
nxpandroidc7611652015-09-23 16:42:05 +05302854
nxf24591c1cbeab2018-02-21 17:32:26 +05302855 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
nxpandroidc7611652015-09-23 16:42:05 +05302856
nxpandroid8f6d0532017-07-12 18:25:30 +05302857 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
2858 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
2859 (rw_cb.tcb.i93.p_retry_cmd) &&
2860 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
2861 rw_cb.tcb.i93.retry_count++;
nxf24591c1cbeab2018-02-21 17:32:26 +05302862 LOG(ERROR) << StringPrintf("retry_count = %d", rw_cb.tcb.i93.retry_count);
nxpandroidc7611652015-09-23 16:42:05 +05302863
nxpandroid8f6d0532017-07-12 18:25:30 +05302864 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2865 rw_cb.tcb.i93.p_retry_cmd = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05302866
nxpandroid8f6d0532017-07-12 18:25:30 +05302867 if (rw_i93_send_to_lower(p_buf)) {
2868 return;
2869 }
nxpandroidc7611652015-09-23 16:42:05 +05302870 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302871
2872 /* all retrial is done or failed to send command to lower layer */
2873 if (rw_cb.tcb.i93.p_retry_cmd) {
2874 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
2875 rw_cb.tcb.i93.p_retry_cmd = NULL;
2876 rw_cb.tcb.i93.retry_count = 0;
nxpandroidc7611652015-09-23 16:42:05 +05302877 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302878 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
2879 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302880 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
nxpandroid8f6d0532017-07-12 18:25:30 +05302881 }
nxpandroidc7611652015-09-23 16:42:05 +05302882}
2883
2884/*******************************************************************************
2885**
2886** Function rw_i93_data_cback
2887**
2888** Description This callback function receives the data from NFCC.
2889**
2890** Returns none
2891**
2892*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302893static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
2894 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302895 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2896 NFC_HDR* p_resp;
2897 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05302898
nxpandroid8f6d0532017-07-12 18:25:30 +05302899 uint8_t begin_state = p_i93->state;
nxpandroidc7611652015-09-23 16:42:05 +05302900
nxf24591c1cbeab2018-02-21 17:32:26 +05302901 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
nxpandroidc7611652015-09-23 16:42:05 +05302902
nxf24591c1cbeab2018-02-21 17:32:26 +05302903 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
2904 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302905 nfc_stop_quick_timer(&p_i93->timer);
nxf24591c1cbeab2018-02-21 17:32:26 +05302906
2907 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302908 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
2909 p_i93->retry_count++;
nxpandroidc7611652015-09-23 16:42:05 +05302910
nxf24591c1cbeab2018-02-21 17:32:26 +05302911 LOG(ERROR) << StringPrintf("retry_count = %d", p_i93->retry_count);
nxpandroidc7611652015-09-23 16:42:05 +05302912
nxpandroid8f6d0532017-07-12 18:25:30 +05302913 p_resp = p_i93->p_retry_cmd;
2914 p_i93->p_retry_cmd = NULL;
2915 if (rw_i93_send_to_lower(p_resp)) {
2916 return;
nxpandroidc7611652015-09-23 16:42:05 +05302917 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302918 }
nxpandroidc7611652015-09-23 16:42:05 +05302919
nxpandroid8f6d0532017-07-12 18:25:30 +05302920 /* all retrial is done or failed to send command to lower layer */
2921 if (p_i93->p_retry_cmd) {
2922 GKI_freebuf(p_i93->p_retry_cmd);
nxpandroidc7611652015-09-23 16:42:05 +05302923 p_i93->p_retry_cmd = NULL;
2924 p_i93->retry_count = 0;
nxpandroid8f6d0532017-07-12 18:25:30 +05302925 }
2926
2927 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
2928 } else {
2929 /* free retry buffer */
2930 if (p_i93->p_retry_cmd) {
2931 GKI_freebuf(p_i93->p_retry_cmd);
2932 p_i93->p_retry_cmd = NULL;
2933 p_i93->retry_count = 0;
2934 }
2935 NFC_SetStaticRfCback(NULL);
2936 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
nxpandroidc7611652015-09-23 16:42:05 +05302937 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302938 return;
2939 }
nxpandroidc7611652015-09-23 16:42:05 +05302940
nxpandroid8f6d0532017-07-12 18:25:30 +05302941 if (event != NFC_DATA_CEVT) {
2942 return;
2943 }
2944
2945 p_resp = (NFC_HDR*)p_data->data.p_data;
2946
2947 nfc_stop_quick_timer(&p_i93->timer);
2948
2949 /* free retry buffer */
2950 if (p_i93->p_retry_cmd) {
2951 GKI_freebuf(p_i93->p_retry_cmd);
2952 p_i93->p_retry_cmd = NULL;
2953 p_i93->retry_count = 0;
2954 }
2955
nxf24591c1cbeab2018-02-21 17:32:26 +05302956 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2957 "RW I93 state: <%s (%d)>", rw_i93_get_state_name(p_i93->state).c_str(),
2958 p_i93->state);
nxpandroidc7611652015-09-23 16:42:05 +05302959
nxpandroid8f6d0532017-07-12 18:25:30 +05302960 switch (p_i93->state) {
nxpandroidc7611652015-09-23 16:42:05 +05302961 case RW_I93_STATE_IDLE:
nxpandroid8f6d0532017-07-12 18:25:30 +05302962 /* Unexpected Response from VICC, it should be raw frame response */
2963 /* forward to upper layer without parsing */
2964 p_i93->sent_cmd = 0;
2965 if (rw_cb.p_cback) {
2966 rw_data.raw_frame.status = p_data->data.status;
2967 rw_data.raw_frame.p_data = p_resp;
2968 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
2969 p_resp = NULL;
2970 } else {
2971 GKI_freebuf(p_resp);
2972 }
2973 break;
nxpandroidc7611652015-09-23 16:42:05 +05302974 case RW_I93_STATE_BUSY:
nxpandroid8f6d0532017-07-12 18:25:30 +05302975 p_i93->state = RW_I93_STATE_IDLE;
2976 rw_i93_send_to_upper(p_resp);
2977 GKI_freebuf(p_resp);
2978 break;
nxpandroidc7611652015-09-23 16:42:05 +05302979
2980 case RW_I93_STATE_DETECT_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302981 rw_i93_sm_detect_ndef(p_resp);
2982 GKI_freebuf(p_resp);
2983 break;
nxpandroidc7611652015-09-23 16:42:05 +05302984
2985 case RW_I93_STATE_READ_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302986 rw_i93_sm_read_ndef(p_resp);
2987 /* p_resp may send upper lyaer */
2988 break;
nxpandroidc7611652015-09-23 16:42:05 +05302989
2990 case RW_I93_STATE_UPDATE_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05302991 rw_i93_sm_update_ndef(p_resp);
2992 GKI_freebuf(p_resp);
2993 break;
nxpandroidc7611652015-09-23 16:42:05 +05302994
2995 case RW_I93_STATE_FORMAT:
nxpandroid8f6d0532017-07-12 18:25:30 +05302996 rw_i93_sm_format(p_resp);
2997 GKI_freebuf(p_resp);
2998 break;
nxpandroidc7611652015-09-23 16:42:05 +05302999
3000 case RW_I93_STATE_SET_READ_ONLY:
nxpandroid8f6d0532017-07-12 18:25:30 +05303001 rw_i93_sm_set_read_only(p_resp);
3002 GKI_freebuf(p_resp);
3003 break;
nxpandroidc7611652015-09-23 16:42:05 +05303004
3005 case RW_I93_STATE_PRESENCE_CHECK:
nxpandroid8f6d0532017-07-12 18:25:30 +05303006 p_i93->state = RW_I93_STATE_IDLE;
3007 p_i93->sent_cmd = 0;
nxpandroidc7611652015-09-23 16:42:05 +05303008
nxpandroid8f6d0532017-07-12 18:25:30 +05303009 /* if any response, send presence check with ok */
3010 rw_data.status = NFC_STATUS_OK;
3011 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3012 GKI_freebuf(p_resp);
3013 break;
nxpandroidc7611652015-09-23 16:42:05 +05303014
3015 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05303016 LOG(ERROR) << StringPrintf("invalid state=%d", p_i93->state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303017 GKI_freebuf(p_resp);
3018 break;
3019 }
nxpandroidc7611652015-09-23 16:42:05 +05303020
nxpandroid8f6d0532017-07-12 18:25:30 +05303021 if (begin_state != p_i93->state) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303022 DLOG_IF(INFO, nfc_debug_enabled)
3023 << StringPrintf("RW I93 state changed:<%s> -> <%s>",
3024 rw_i93_get_state_name(begin_state).c_str(),
3025 rw_i93_get_state_name(p_i93->state).c_str());
nxpandroid8f6d0532017-07-12 18:25:30 +05303026 }
nxpandroidc7611652015-09-23 16:42:05 +05303027}
3028
3029/*******************************************************************************
3030**
3031** Function rw_i93_select
3032**
nxf24591c1cbeab2018-02-21 17:32:26 +05303033** Description Initialise ISO 15693 / T5T RW
nxpandroidc7611652015-09-23 16:42:05 +05303034**
3035** Returns NFC_STATUS_OK if success
3036**
3037*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303038tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
3039 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
3040 uint8_t uid[I93_UID_BYTE_LEN], *p;
nxpandroidc7611652015-09-23 16:42:05 +05303041
nxf24591c1cbeab2018-02-21 17:32:26 +05303042 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303043
nxpandroid8f6d0532017-07-12 18:25:30 +05303044 NFC_SetStaticRfCback(rw_i93_data_cback);
nxpandroidc7611652015-09-23 16:42:05 +05303045
nxpandroid8f6d0532017-07-12 18:25:30 +05303046 p_i93->state = RW_I93_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05303047
nxpandroid8f6d0532017-07-12 18:25:30 +05303048 /* convert UID to big endian format - MSB(0xE0) in first byte */
3049 p = uid;
3050 STREAM_TO_ARRAY8(p, p_uid);
nxpandroidc7611652015-09-23 16:42:05 +05303051
nxpandroid8f6d0532017-07-12 18:25:30 +05303052 rw_i93_get_product_version(uid);
nxpandroidc7611652015-09-23 16:42:05 +05303053
nxpandroid8f6d0532017-07-12 18:25:30 +05303054 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05303055}
3056
3057/*******************************************************************************
3058**
3059** Function RW_I93Inventory
3060**
3061** Description This function send Inventory command with/without AFI
3062** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3063**
3064** RW_I93_RESPONSE_EVT will be returned
3065**
3066** Returns NFC_STATUS_OK if success
3067** NFC_STATUS_NO_BUFFERS if out of buffer
3068** NFC_STATUS_BUSY if busy
3069** NFC_STATUS_FAILED if other error
3070**
3071*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303072tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3073 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303074
nxf24591c1cbeab2018-02-21 17:32:26 +05303075 DLOG_IF(INFO, nfc_debug_enabled)
3076 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
nxpandroidc7611652015-09-23 16:42:05 +05303077
nxpandroid8f6d0532017-07-12 18:25:30 +05303078 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303079 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3080 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303081 return NFC_STATUS_BUSY;
3082 }
nxpandroidc7611652015-09-23 16:42:05 +05303083
nxpandroid8f6d0532017-07-12 18:25:30 +05303084 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
nxpandroidc7611652015-09-23 16:42:05 +05303085
nxpandroid8f6d0532017-07-12 18:25:30 +05303086 if (status == NFC_STATUS_OK) {
3087 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3088 }
nxpandroidc7611652015-09-23 16:42:05 +05303089
nxpandroid8f6d0532017-07-12 18:25:30 +05303090 return (status);
nxpandroidc7611652015-09-23 16:42:05 +05303091}
3092
3093/*******************************************************************************
3094**
3095** Function RW_I93StayQuiet
3096**
3097** Description This function send Inventory command
3098**
3099** RW_I93_CMD_CMPL_EVT will be returned
3100**
3101** Returns NFC_STATUS_OK if success
3102** NFC_STATUS_NO_BUFFERS if out of buffer
3103** NFC_STATUS_BUSY if busy
3104** NFC_STATUS_FAILED if other error
3105**
3106*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303107tNFC_STATUS RW_I93StayQuiet(void) {
3108 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303109
nxf24591c1cbeab2018-02-21 17:32:26 +05303110 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303111
nxpandroid8f6d0532017-07-12 18:25:30 +05303112 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303113 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3114 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303115 return NFC_STATUS_BUSY;
3116 }
nxpandroidc7611652015-09-23 16:42:05 +05303117
nxpandroid8f6d0532017-07-12 18:25:30 +05303118 status = rw_i93_send_cmd_stay_quiet();
3119 if (status == NFC_STATUS_OK) {
3120 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3121 }
nxpandroidc7611652015-09-23 16:42:05 +05303122
nxpandroid8f6d0532017-07-12 18:25:30 +05303123 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303124}
3125
3126/*******************************************************************************
3127**
3128** Function RW_I93ReadSingleBlock
3129**
3130** Description This function send Read Single Block command
3131**
3132** RW_I93_RESPONSE_EVT will be returned
3133**
3134** Returns NFC_STATUS_OK if success
3135** NFC_STATUS_NO_BUFFERS if out of buffer
3136** NFC_STATUS_BUSY if busy
3137** NFC_STATUS_FAILED if other error
3138**
3139*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303140tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3141 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303142
nxf24591c1cbeab2018-02-21 17:32:26 +05303143 DLOG_IF(INFO, nfc_debug_enabled)
3144 << StringPrintf("block_number:0x%02X", block_number);
nxpandroidc7611652015-09-23 16:42:05 +05303145
nxpandroid8f6d0532017-07-12 18:25:30 +05303146 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303147 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3148 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303149 return NFC_STATUS_BUSY;
3150 }
nxpandroidc7611652015-09-23 16:42:05 +05303151
nxpandroid8f6d0532017-07-12 18:25:30 +05303152 status = rw_i93_send_cmd_read_single_block(block_number, false);
3153 if (status == NFC_STATUS_OK) {
3154 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3155 }
nxpandroidc7611652015-09-23 16:42:05 +05303156
nxpandroid8f6d0532017-07-12 18:25:30 +05303157 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303158}
3159
3160/*******************************************************************************
3161**
3162** Function RW_I93WriteSingleBlock
3163**
3164** Description This function send Write Single Block command
nxpandroid8f6d0532017-07-12 18:25:30 +05303165** Application must get block size first by calling
3166** RW_I93GetSysInfo().
nxpandroidc7611652015-09-23 16:42:05 +05303167**
3168** RW_I93_CMD_CMPL_EVT will be returned
3169**
3170** Returns NFC_STATUS_OK if success
3171** NFC_STATUS_NO_BUFFERS if out of buffer
3172** NFC_STATUS_BUSY if busy
3173** NFC_STATUS_FAILED if other error
3174**
3175*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303176tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3177 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303178
nxf24591c1cbeab2018-02-21 17:32:26 +05303179 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303180
nxpandroid8f6d0532017-07-12 18:25:30 +05303181 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303182 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3183 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303184 return NFC_STATUS_BUSY;
3185 }
nxpandroidc7611652015-09-23 16:42:05 +05303186
nxpandroid8f6d0532017-07-12 18:25:30 +05303187 if (rw_cb.tcb.i93.block_size == 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303188 LOG(ERROR) << StringPrintf("Block size is unknown");
nxpandroid8f6d0532017-07-12 18:25:30 +05303189 return NFC_STATUS_FAILED;
3190 }
nxpandroidc7611652015-09-23 16:42:05 +05303191
nxpandroid8f6d0532017-07-12 18:25:30 +05303192 status = rw_i93_send_cmd_write_single_block(block_number, p_data);
3193 if (status == NFC_STATUS_OK) {
3194 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3195 }
nxpandroidc7611652015-09-23 16:42:05 +05303196
nxpandroid8f6d0532017-07-12 18:25:30 +05303197 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303198}
3199
3200/*******************************************************************************
3201**
3202** Function RW_I93LockBlock
3203**
3204** Description This function send Lock Block command
3205**
3206** RW_I93_CMD_CMPL_EVT will be returned
3207**
3208** Returns NFC_STATUS_OK if success
3209** NFC_STATUS_NO_BUFFERS if out of buffer
3210** NFC_STATUS_BUSY if busy
3211** NFC_STATUS_FAILED if other error
3212**
3213*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303214tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3215 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303216
nxf24591c1cbeab2018-02-21 17:32:26 +05303217 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303218
nxpandroid8f6d0532017-07-12 18:25:30 +05303219 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303220 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3221 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303222 return NFC_STATUS_BUSY;
3223 }
nxpandroidc7611652015-09-23 16:42:05 +05303224
nxpandroid8f6d0532017-07-12 18:25:30 +05303225 status = rw_i93_send_cmd_lock_block(block_number);
3226 if (status == NFC_STATUS_OK) {
3227 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3228 }
nxpandroidc7611652015-09-23 16:42:05 +05303229
nxpandroid8f6d0532017-07-12 18:25:30 +05303230 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303231}
3232
3233/*******************************************************************************
3234**
3235** Function RW_I93ReadMultipleBlocks
3236**
3237** Description This function send Read Multiple Blocks command
3238**
3239** RW_I93_RESPONSE_EVT will be returned
3240**
3241** Returns NFC_STATUS_OK if success
3242** NFC_STATUS_NO_BUFFERS if out of buffer
3243** NFC_STATUS_BUSY if busy
3244** NFC_STATUS_FAILED if other error
3245**
3246*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303247tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3248 uint16_t number_blocks) {
3249 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303250
nxf24591c1cbeab2018-02-21 17:32:26 +05303251 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303252
nxpandroid8f6d0532017-07-12 18:25:30 +05303253 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303254 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3255 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303256 return NFC_STATUS_BUSY;
3257 }
nxpandroidc7611652015-09-23 16:42:05 +05303258
nxpandroid8f6d0532017-07-12 18:25:30 +05303259 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3260 if (status == NFC_STATUS_OK) {
3261 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3262 }
nxpandroidc7611652015-09-23 16:42:05 +05303263
nxpandroid8f6d0532017-07-12 18:25:30 +05303264 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303265}
3266
3267/*******************************************************************************
3268**
3269** Function RW_I93WriteMultipleBlocks
3270**
3271** Description This function send Write Multiple Blocks command
3272**
3273** RW_I93_CMD_CMPL_EVT will be returned
3274**
3275** Returns NFC_STATUS_OK if success
3276** NFC_STATUS_NO_BUFFERS if out of buffer
3277** NFC_STATUS_BUSY if busy
3278** NFC_STATUS_FAILED if other error
3279**
3280*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05303281tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
nxpandroid8f6d0532017-07-12 18:25:30 +05303282 uint16_t number_blocks, uint8_t* p_data) {
3283 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303284
nxf24591c1cbeab2018-02-21 17:32:26 +05303285 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303286
nxpandroid8f6d0532017-07-12 18:25:30 +05303287 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303288 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3289 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303290 return NFC_STATUS_BUSY;
3291 }
nxpandroidc7611652015-09-23 16:42:05 +05303292
nxpandroid8f6d0532017-07-12 18:25:30 +05303293 if (rw_cb.tcb.i93.block_size == 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303294 LOG(ERROR) << StringPrintf("Block size is unknown");
nxpandroid8f6d0532017-07-12 18:25:30 +05303295 return NFC_STATUS_FAILED;
3296 }
nxpandroidc7611652015-09-23 16:42:05 +05303297
nxpandroid8f6d0532017-07-12 18:25:30 +05303298 status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
3299 p_data);
3300 if (status == NFC_STATUS_OK) {
3301 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3302 }
nxpandroidc7611652015-09-23 16:42:05 +05303303
nxpandroid8f6d0532017-07-12 18:25:30 +05303304 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303305}
3306
3307/*******************************************************************************
3308**
3309** Function RW_I93Select
3310**
3311** Description This function send Select command
3312**
3313** UID[0]: 0xE0, MSB
3314** UID[1]: IC Mfg Code
3315** ...
3316** UID[7]: LSB
3317**
3318** RW_I93_CMD_CMPL_EVT will be returned
3319**
3320** Returns NFC_STATUS_OK if success
3321** NFC_STATUS_NO_BUFFERS if out of buffer
3322** NFC_STATUS_BUSY if busy
3323** NFC_STATUS_FAILED if other error
3324**
3325*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303326tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3327 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303328
nxf24591c1cbeab2018-02-21 17:32:26 +05303329 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303330
nxpandroid8f6d0532017-07-12 18:25:30 +05303331 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303332 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3333 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303334 return NFC_STATUS_BUSY;
3335 }
3336
3337 if (p_uid) {
3338 status = rw_i93_send_cmd_select(p_uid);
3339 if (status == NFC_STATUS_OK) {
3340 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
nxpandroidc7611652015-09-23 16:42:05 +05303341 }
nxpandroid8f6d0532017-07-12 18:25:30 +05303342 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05303343 LOG(ERROR) << StringPrintf("UID shall be provided");
nxpandroid8f6d0532017-07-12 18:25:30 +05303344 status = NFC_STATUS_FAILED;
3345 }
nxpandroidc7611652015-09-23 16:42:05 +05303346
nxpandroid8f6d0532017-07-12 18:25:30 +05303347 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303348}
3349
3350/*******************************************************************************
3351**
3352** Function RW_I93ResetToReady
3353**
3354** Description This function send Reset To Ready command
3355**
3356** RW_I93_CMD_CMPL_EVT will be returned
3357**
3358** Returns NFC_STATUS_OK if success
3359** NFC_STATUS_NO_BUFFERS if out of buffer
3360** NFC_STATUS_BUSY if busy
3361** NFC_STATUS_FAILED if other error
3362**
3363*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303364tNFC_STATUS RW_I93ResetToReady(void) {
3365 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303366
nxf24591c1cbeab2018-02-21 17:32:26 +05303367 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303368
nxpandroid8f6d0532017-07-12 18:25:30 +05303369 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303370 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3371 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303372 return NFC_STATUS_BUSY;
3373 }
nxpandroidc7611652015-09-23 16:42:05 +05303374
nxpandroid8f6d0532017-07-12 18:25:30 +05303375 status = rw_i93_send_cmd_reset_to_ready();
3376 if (status == NFC_STATUS_OK) {
3377 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3378 }
nxpandroidc7611652015-09-23 16:42:05 +05303379
nxpandroid8f6d0532017-07-12 18:25:30 +05303380 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303381}
3382
3383/*******************************************************************************
3384**
3385** Function RW_I93WriteAFI
3386**
3387** Description This function send Write AFI command
3388**
3389** RW_I93_CMD_CMPL_EVT will be returned
3390**
3391** Returns NFC_STATUS_OK if success
3392** NFC_STATUS_NO_BUFFERS if out of buffer
3393** NFC_STATUS_BUSY if busy
3394** NFC_STATUS_FAILED if other error
3395**
3396*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303397tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3398 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303399
nxf24591c1cbeab2018-02-21 17:32:26 +05303400 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303401
nxpandroid8f6d0532017-07-12 18:25:30 +05303402 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303403 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3404 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303405 return NFC_STATUS_BUSY;
3406 }
nxpandroidc7611652015-09-23 16:42:05 +05303407
nxpandroid8f6d0532017-07-12 18:25:30 +05303408 status = rw_i93_send_cmd_write_afi(afi);
3409 if (status == NFC_STATUS_OK) {
3410 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3411 }
nxpandroidc7611652015-09-23 16:42:05 +05303412
nxpandroid8f6d0532017-07-12 18:25:30 +05303413 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303414}
3415
3416/*******************************************************************************
3417**
3418** Function RW_I93LockAFI
3419**
3420** Description This function send Lock AFI command
3421**
3422** RW_I93_CMD_CMPL_EVT will be returned
3423**
3424** Returns NFC_STATUS_OK if success
3425** NFC_STATUS_NO_BUFFERS if out of buffer
3426** NFC_STATUS_BUSY if busy
3427** NFC_STATUS_FAILED if other error
3428**
3429*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303430tNFC_STATUS RW_I93LockAFI(void) {
3431 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303432
nxf24591c1cbeab2018-02-21 17:32:26 +05303433 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303434
nxpandroid8f6d0532017-07-12 18:25:30 +05303435 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303436 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3437 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303438 return NFC_STATUS_BUSY;
3439 }
nxpandroidc7611652015-09-23 16:42:05 +05303440
nxpandroid8f6d0532017-07-12 18:25:30 +05303441 status = rw_i93_send_cmd_lock_afi();
3442 if (status == NFC_STATUS_OK) {
3443 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3444 }
nxpandroidc7611652015-09-23 16:42:05 +05303445
nxpandroid8f6d0532017-07-12 18:25:30 +05303446 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303447}
3448
3449/*******************************************************************************
3450**
3451** Function RW_I93WriteDSFID
3452**
3453** Description This function send Write DSFID command
3454**
3455** RW_I93_CMD_CMPL_EVT will be returned
3456**
3457** Returns NFC_STATUS_OK if success
3458** NFC_STATUS_NO_BUFFERS if out of buffer
3459** NFC_STATUS_BUSY if busy
3460** NFC_STATUS_FAILED if other error
3461**
3462*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303463tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3464 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303465
nxf24591c1cbeab2018-02-21 17:32:26 +05303466 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303467
nxpandroid8f6d0532017-07-12 18:25:30 +05303468 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303469 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3470 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303471 return NFC_STATUS_BUSY;
3472 }
nxpandroidc7611652015-09-23 16:42:05 +05303473
nxpandroid8f6d0532017-07-12 18:25:30 +05303474 status = rw_i93_send_cmd_write_dsfid(dsfid);
3475 if (status == NFC_STATUS_OK) {
3476 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3477 }
nxpandroidc7611652015-09-23 16:42:05 +05303478
nxpandroid8f6d0532017-07-12 18:25:30 +05303479 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303480}
3481
3482/*******************************************************************************
3483**
3484** Function RW_I93LockDSFID
3485**
3486** Description This function send Lock DSFID command
3487**
3488** RW_I93_CMD_CMPL_EVT will be returned
3489**
3490** Returns NFC_STATUS_OK if success
3491** NFC_STATUS_NO_BUFFERS if out of buffer
3492** NFC_STATUS_BUSY if busy
3493** NFC_STATUS_FAILED if other error
3494**
3495*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303496tNFC_STATUS RW_I93LockDSFID(void) {
3497 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303498
nxf24591c1cbeab2018-02-21 17:32:26 +05303499 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303500
nxpandroid8f6d0532017-07-12 18:25:30 +05303501 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303502 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3503 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303504 return NFC_STATUS_BUSY;
3505 }
nxpandroidc7611652015-09-23 16:42:05 +05303506
nxpandroid8f6d0532017-07-12 18:25:30 +05303507 status = rw_i93_send_cmd_lock_dsfid();
3508 if (status == NFC_STATUS_OK) {
3509 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3510 }
nxpandroidc7611652015-09-23 16:42:05 +05303511
nxpandroid8f6d0532017-07-12 18:25:30 +05303512 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303513}
3514
3515/*******************************************************************************
3516**
3517** Function RW_I93GetSysInfo
3518**
3519** Description This function send Get System Information command
3520**
3521** RW_I93_RESPONSE_EVT will be returned
3522**
3523** Returns NFC_STATUS_OK if success
3524** NFC_STATUS_NO_BUFFERS if out of buffer
3525** NFC_STATUS_BUSY if busy
3526** NFC_STATUS_FAILED if other error
3527**
3528*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303529tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3530 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303531
nxf24591c1cbeab2018-02-21 17:32:26 +05303532 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303533
nxpandroid8f6d0532017-07-12 18:25:30 +05303534 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303535 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3536 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303537 return NFC_STATUS_BUSY;
3538 }
nxpandroidc7611652015-09-23 16:42:05 +05303539
nxpandroid8f6d0532017-07-12 18:25:30 +05303540 if (p_uid) {
3541 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3542 } else {
3543 status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
3544 }
nxpandroidc7611652015-09-23 16:42:05 +05303545
nxpandroid8f6d0532017-07-12 18:25:30 +05303546 if (status == NFC_STATUS_OK) {
3547 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3548 }
nxpandroidc7611652015-09-23 16:42:05 +05303549
nxpandroid8f6d0532017-07-12 18:25:30 +05303550 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303551}
3552
3553/*******************************************************************************
3554**
3555** Function RW_I93GetMultiBlockSecurityStatus
3556**
nxpandroid8f6d0532017-07-12 18:25:30 +05303557** Description This function send Get Multiple Block Security Status
3558** command
nxpandroidc7611652015-09-23 16:42:05 +05303559**
3560** RW_I93_RESPONSE_EVT will be returned
3561**
3562** Returns NFC_STATUS_OK if success
3563** NFC_STATUS_NO_BUFFERS if out of buffer
3564** NFC_STATUS_BUSY if busy
3565** NFC_STATUS_FAILED if other error
3566**
3567*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303568tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3569 uint16_t number_blocks) {
3570 tNFC_STATUS status;
nxpandroidc7611652015-09-23 16:42:05 +05303571
nxf24591c1cbeab2018-02-21 17:32:26 +05303572 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303573
nxpandroid8f6d0532017-07-12 18:25:30 +05303574 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303575 LOG(ERROR) << StringPrintf(
3576 "Unable to start command at state "
nxpandroid8f6d0532017-07-12 18:25:30 +05303577 "(0x%X)",
3578 rw_cb.tcb.i93.state);
3579 return NFC_STATUS_BUSY;
3580 }
nxpandroidc7611652015-09-23 16:42:05 +05303581
nxpandroid8f6d0532017-07-12 18:25:30 +05303582 status =
3583 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3584 if (status == NFC_STATUS_OK) {
3585 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3586 }
nxpandroidc7611652015-09-23 16:42:05 +05303587
nxpandroid8f6d0532017-07-12 18:25:30 +05303588 return status;
nxpandroidc7611652015-09-23 16:42:05 +05303589}
3590
3591/*******************************************************************************
3592**
3593** Function RW_I93DetectNDef
3594**
3595** Description This function performs NDEF detection procedure
3596**
3597** RW_I93_NDEF_DETECT_EVT will be returned
3598**
3599** Returns NFC_STATUS_OK if success
3600** NFC_STATUS_FAILED if busy or other error
3601**
3602*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303603tNFC_STATUS RW_I93DetectNDef(void) {
3604 tNFC_STATUS status;
3605 tRW_I93_RW_SUBSTATE sub_state;
nxpandroidc7611652015-09-23 16:42:05 +05303606
nxf24591c1cbeab2018-02-21 17:32:26 +05303607 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303608
nxpandroid8f6d0532017-07-12 18:25:30 +05303609 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303610 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3611 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303612 return NFC_STATUS_FAILED;
3613 }
nxpandroidc7611652015-09-23 16:42:05 +05303614
nxpandroid8f6d0532017-07-12 18:25:30 +05303615 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
3616 status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
3617 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3618 } else if ((rw_cb.tcb.i93.num_block == 0) ||
3619 (rw_cb.tcb.i93.block_size == 0)) {
3620 status =
3621 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3622 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
nxpandroidc7611652015-09-23 16:42:05 +05303623
nxpandroid8f6d0532017-07-12 18:25:30 +05303624 /* clear all flags */
3625 rw_cb.tcb.i93.intl_flags = 0;
3626 } else {
3627 /* read CC in the first block */
3628 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3629 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3630 }
nxpandroidc7611652015-09-23 16:42:05 +05303631
nxpandroid8f6d0532017-07-12 18:25:30 +05303632 if (status == NFC_STATUS_OK) {
3633 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3634 rw_cb.tcb.i93.sub_state = sub_state;
nxpandroidc7611652015-09-23 16:42:05 +05303635
nxpandroid8f6d0532017-07-12 18:25:30 +05303636 /* clear flags except flag for 2 bytes of number of blocks */
3637 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3638 }
nxpandroidc7611652015-09-23 16:42:05 +05303639
nxpandroid8f6d0532017-07-12 18:25:30 +05303640 return (status);
nxpandroidc7611652015-09-23 16:42:05 +05303641}
3642
3643/*******************************************************************************
3644**
3645** Function RW_I93ReadNDef
3646**
3647** Description This function performs NDEF read procedure
3648** Note: RW_I93DetectNDef () must be called before using this
3649**
3650** The following event will be returned
3651** RW_I93_NDEF_READ_EVT for each segmented NDEF message
nxpandroid8f6d0532017-07-12 18:25:30 +05303652** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3653** complete NDEF
nxpandroidc7611652015-09-23 16:42:05 +05303654** RW_I93_NDEF_READ_FAIL_EVT for failure
3655**
3656** Returns NFC_STATUS_OK if success
3657** NFC_STATUS_FAILED if I93 is busy or other error
3658**
3659*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303660tNFC_STATUS RW_I93ReadNDef(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303661 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303662
nxpandroid8f6d0532017-07-12 18:25:30 +05303663 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303664 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3665 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303666 return NFC_STATUS_FAILED;
3667 }
3668
3669 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
3670 (rw_cb.tcb.i93.ndef_length > 0)) {
3671 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3672 rw_cb.tcb.i93.rw_length = 0;
3673
3674 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
3675 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3676 } else {
3677 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05303678 }
nxpandroid8f6d0532017-07-12 18:25:30 +05303679 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05303680 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05303681 return NFC_STATUS_FAILED;
3682 }
nxpandroidc7611652015-09-23 16:42:05 +05303683
nxpandroid8f6d0532017-07-12 18:25:30 +05303684 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05303685}
3686
3687/*******************************************************************************
3688**
3689** Function RW_I93UpdateNDef
3690**
3691** Description This function performs NDEF update procedure
3692** Note: RW_I93DetectNDef () must be called before using this
nxpandroid8f6d0532017-07-12 18:25:30 +05303693** Updating data must not be removed until returning
3694** event
nxpandroidc7611652015-09-23 16:42:05 +05303695**
3696** The following event will be returned
3697** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3698** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3699**
3700** Returns NFC_STATUS_OK if success
3701** NFC_STATUS_FAILED if I93 is busy or other error
3702**
3703*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303704tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3705 uint16_t block_number;
nxpandroidc7611652015-09-23 16:42:05 +05303706
nxf24591c1cbeab2018-02-21 17:32:26 +05303707 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
nxpandroidc7611652015-09-23 16:42:05 +05303708
nxpandroid8f6d0532017-07-12 18:25:30 +05303709 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303710 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3711 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303712 return NFC_STATUS_FAILED;
3713 }
3714
3715 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3716 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303717 LOG(ERROR) << StringPrintf("NDEF is read-only");
nxpandroid8f6d0532017-07-12 18:25:30 +05303718 return NFC_STATUS_FAILED;
3719 }
3720 if (rw_cb.tcb.i93.max_ndef_length < length) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303721 LOG(ERROR) << StringPrintf(
3722 "data (%d bytes) is more than max NDEF length "
nxpandroid8f6d0532017-07-12 18:25:30 +05303723 "(%d)",
3724 length, rw_cb.tcb.i93.max_ndef_length);
3725 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05303726 }
3727
nxpandroid8f6d0532017-07-12 18:25:30 +05303728 rw_cb.tcb.i93.ndef_length = length;
3729 rw_cb.tcb.i93.p_update_data = p_data;
nxpandroidc7611652015-09-23 16:42:05 +05303730
nxpandroid8f6d0532017-07-12 18:25:30 +05303731 /* read length field */
3732 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3733 rw_cb.tcb.i93.rw_length = 0;
nxpandroidc7611652015-09-23 16:42:05 +05303734
nxpandroid8f6d0532017-07-12 18:25:30 +05303735 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
nxpandroidc7611652015-09-23 16:42:05 +05303736
nxpandroid8f6d0532017-07-12 18:25:30 +05303737 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
3738 NFC_STATUS_OK) {
3739 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3740 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3741 } else {
3742 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05303743 }
nxpandroid8f6d0532017-07-12 18:25:30 +05303744 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05303745 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05303746 return NFC_STATUS_FAILED;
3747 }
nxpandroidc7611652015-09-23 16:42:05 +05303748
nxpandroid8f6d0532017-07-12 18:25:30 +05303749 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05303750}
3751
3752/*******************************************************************************
3753**
3754** Function RW_I93FormatNDef
3755**
3756** Description This function performs formatting procedure
3757**
3758** RW_I93_FORMAT_CPLT_EVT will be returned
3759**
3760** Returns NFC_STATUS_OK if success
3761** NFC_STATUS_FAILED if busy or other error
3762**
3763*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303764tNFC_STATUS RW_I93FormatNDef(void) {
3765 tNFC_STATUS status;
3766 tRW_I93_RW_SUBSTATE sub_state;
nxpandroidc7611652015-09-23 16:42:05 +05303767
nxf24591c1cbeab2018-02-21 17:32:26 +05303768 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303769
nxpandroid8f6d0532017-07-12 18:25:30 +05303770 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303771 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3772 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303773 return NFC_STATUS_FAILED;
3774 }
nxpandroidc7611652015-09-23 16:42:05 +05303775
nxpandroid8f6d0532017-07-12 18:25:30 +05303776 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
3777 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
3778 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
3779 */
3780 rw_cb.tcb.i93.rw_offset = 0;
nxpandroidc7611652015-09-23 16:42:05 +05303781
nxpandroid8f6d0532017-07-12 18:25:30 +05303782 /* read blocks with option flag to get block security status */
3783 status = rw_i93_send_cmd_read_single_block(0x0000, true);
3784 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
3785 } else {
3786 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3787 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3788 }
nxpandroidc7611652015-09-23 16:42:05 +05303789
nxpandroid8f6d0532017-07-12 18:25:30 +05303790 if (status == NFC_STATUS_OK) {
3791 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
3792 rw_cb.tcb.i93.sub_state = sub_state;
3793 rw_cb.tcb.i93.intl_flags = 0;
3794 }
nxpandroidc7611652015-09-23 16:42:05 +05303795
nxpandroid8f6d0532017-07-12 18:25:30 +05303796 return (status);
nxpandroidc7611652015-09-23 16:42:05 +05303797}
3798
3799/*******************************************************************************
3800**
3801** Function RW_I93SetTagReadOnly
3802**
3803** Description This function performs NDEF read-only procedure
3804** Note: RW_I93DetectNDef () must be called before using this
nxpandroid8f6d0532017-07-12 18:25:30 +05303805** Updating data must not be removed until returning
3806** event
nxpandroidc7611652015-09-23 16:42:05 +05303807**
3808** The RW_I93_SET_TAG_RO_EVT event will be returned.
3809**
3810** Returns NFC_STATUS_OK if success
3811** NFC_STATUS_FAILED if I93 is busy or other error
3812**
3813*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303814tNFC_STATUS RW_I93SetTagReadOnly(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303815 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303816
nxpandroid8f6d0532017-07-12 18:25:30 +05303817 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303818 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3819 rw_cb.tcb.i93.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05303820 return NFC_STATUS_FAILED;
3821 }
3822
3823 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3824 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
nxf24591c1cbeab2018-02-21 17:32:26 +05303825 LOG(ERROR) << StringPrintf("NDEF is already read-only");
nxpandroid8f6d0532017-07-12 18:25:30 +05303826 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05303827 }
3828
nxpandroid8f6d0532017-07-12 18:25:30 +05303829 /* get CC in the first block */
3830 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
3831 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
3832 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
3833 } else {
3834 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05303835 }
nxpandroid8f6d0532017-07-12 18:25:30 +05303836 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05303837 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05303838 return NFC_STATUS_FAILED;
3839 }
nxpandroidc7611652015-09-23 16:42:05 +05303840
nxpandroid8f6d0532017-07-12 18:25:30 +05303841 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05303842}
3843
3844/*****************************************************************************
3845**
3846** Function RW_I93PresenceCheck
3847**
3848** Description Check if the tag is still in the field.
3849**
3850** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
3851** presence or non-presence.
3852**
3853** Returns NFC_STATUS_OK, if raw data frame sent
nxpandroid8f6d0532017-07-12 18:25:30 +05303854** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3855** operation
nxpandroidc7611652015-09-23 16:42:05 +05303856** NFC_STATUS_FAILED: other error
3857**
3858*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05303859tNFC_STATUS RW_I93PresenceCheck(void) {
3860 tNFC_STATUS status;
3861 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05303862
nxf24591c1cbeab2018-02-21 17:32:26 +05303863 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05303864
nxpandroid8f6d0532017-07-12 18:25:30 +05303865 if (!rw_cb.p_cback) {
3866 return NFC_STATUS_FAILED;
3867 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
3868 evt_data.status = NFC_STATUS_FAILED;
3869 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
nxpandroidc7611652015-09-23 16:42:05 +05303870
nxpandroid8f6d0532017-07-12 18:25:30 +05303871 return NFC_STATUS_OK;
3872 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3873 return NFC_STATUS_BUSY;
3874 } else {
3875 /* The support of AFI by the VICC is optional, so do not include AFI */
3876 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3877
3878 if (status == NFC_STATUS_OK) {
3879 /* do not retry during presence check */
3880 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
3881 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
nxpandroidc7611652015-09-23 16:42:05 +05303882 }
nxpandroid8f6d0532017-07-12 18:25:30 +05303883 }
nxpandroidc7611652015-09-23 16:42:05 +05303884
nxpandroid8f6d0532017-07-12 18:25:30 +05303885 return (status);
nxpandroidc7611652015-09-23 16:42:05 +05303886}
3887
nxpandroidc7611652015-09-23 16:42:05 +05303888/*******************************************************************************
3889**
3890** Function rw_i93_get_state_name
3891**
3892** Description This function returns the state name.
3893**
3894** NOTE conditionally compiled to save memory.
3895**
3896** Returns pointer to the name
3897**
3898*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05303899static std::string rw_i93_get_state_name(uint8_t state) {
nxpandroid8f6d0532017-07-12 18:25:30 +05303900 switch (state) {
nxpandroidc7611652015-09-23 16:42:05 +05303901 case RW_I93_STATE_NOT_ACTIVATED:
nxf24591c1cbeab2018-02-21 17:32:26 +05303902 return "NOT_ACTIVATED";
nxpandroidc7611652015-09-23 16:42:05 +05303903 case RW_I93_STATE_IDLE:
nxf24591c1cbeab2018-02-21 17:32:26 +05303904 return "IDLE";
nxpandroidc7611652015-09-23 16:42:05 +05303905 case RW_I93_STATE_BUSY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303906 return "BUSY";
nxpandroidc7611652015-09-23 16:42:05 +05303907 case RW_I93_STATE_DETECT_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05303908 return "NDEF_DETECTION";
nxpandroidc7611652015-09-23 16:42:05 +05303909 case RW_I93_STATE_READ_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05303910 return "READ_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05303911 case RW_I93_STATE_UPDATE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05303912 return "UPDATE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05303913 case RW_I93_STATE_FORMAT:
nxf24591c1cbeab2018-02-21 17:32:26 +05303914 return "FORMAT";
nxpandroidc7611652015-09-23 16:42:05 +05303915 case RW_I93_STATE_SET_READ_ONLY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303916 return "SET_READ_ONLY";
nxpandroidc7611652015-09-23 16:42:05 +05303917 case RW_I93_STATE_PRESENCE_CHECK:
nxf24591c1cbeab2018-02-21 17:32:26 +05303918 return "PRESENCE_CHECK";
nxpandroidc7611652015-09-23 16:42:05 +05303919 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05303920 return "???? UNKNOWN STATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05303921 }
nxpandroidc7611652015-09-23 16:42:05 +05303922}
3923
3924/*******************************************************************************
3925**
3926** Function rw_i93_get_sub_state_name
3927**
3928** Description This function returns the sub_state name.
3929**
3930** NOTE conditionally compiled to save memory.
3931**
3932** Returns pointer to the name
3933**
3934*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05303935static std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
nxpandroid8f6d0532017-07-12 18:25:30 +05303936 switch (sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05303937 case RW_I93_SUBSTATE_WAIT_UID:
nxf24591c1cbeab2018-02-21 17:32:26 +05303938 return "WAIT_UID";
nxpandroidc7611652015-09-23 16:42:05 +05303939 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
nxf24591c1cbeab2018-02-21 17:32:26 +05303940 return "WAIT_SYS_INFO";
nxpandroidc7611652015-09-23 16:42:05 +05303941 case RW_I93_SUBSTATE_WAIT_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05303942 return "WAIT_CC";
nxpandroidc7611652015-09-23 16:42:05 +05303943 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
nxf24591c1cbeab2018-02-21 17:32:26 +05303944 return "SEARCH_NDEF_TLV";
nxpandroidc7611652015-09-23 16:42:05 +05303945 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
nxf24591c1cbeab2018-02-21 17:32:26 +05303946 return "CHECK_LOCK_STATUS";
nxpandroidc7611652015-09-23 16:42:05 +05303947 case RW_I93_SUBSTATE_RESET_LEN:
nxf24591c1cbeab2018-02-21 17:32:26 +05303948 return "RESET_LEN";
nxpandroidc7611652015-09-23 16:42:05 +05303949 case RW_I93_SUBSTATE_WRITE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05303950 return "WRITE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05303951 case RW_I93_SUBSTATE_UPDATE_LEN:
nxf24591c1cbeab2018-02-21 17:32:26 +05303952 return "UPDATE_LEN";
nxpandroidc7611652015-09-23 16:42:05 +05303953 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
nxf24591c1cbeab2018-02-21 17:32:26 +05303954 return "WAIT_RESET_DSFID_AFI";
nxpandroidc7611652015-09-23 16:42:05 +05303955 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303956 return "CHECK_READ_ONLY";
nxpandroidc7611652015-09-23 16:42:05 +05303957 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
nxf24591c1cbeab2018-02-21 17:32:26 +05303958 return "WRITE_CC_NDEF_TLV";
nxpandroidc7611652015-09-23 16:42:05 +05303959 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05303960 return "WAIT_UPDATE_CC";
nxpandroidc7611652015-09-23 16:42:05 +05303961 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
nxf24591c1cbeab2018-02-21 17:32:26 +05303962 return "LOCK_NDEF_TLV";
nxpandroidc7611652015-09-23 16:42:05 +05303963 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05303964 return "WAIT_LOCK_CC";
nxpandroidc7611652015-09-23 16:42:05 +05303965 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05303966 return "???? UNKNOWN SUBSTATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05303967 }
nxpandroidc7611652015-09-23 16:42:05 +05303968}
3969
3970/*******************************************************************************
3971**
3972** Function rw_i93_get_tag_name
3973**
3974** Description This function returns the tag name.
3975**
3976** NOTE conditionally compiled to save memory.
3977**
3978** Returns pointer to the name
3979**
3980*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05303981static std::string rw_i93_get_tag_name(uint8_t product_version) {
nxpandroid8f6d0532017-07-12 18:25:30 +05303982 switch (product_version) {
nxpandroidc7611652015-09-23 16:42:05 +05303983 case RW_I93_ICODE_SLI:
nxf24591c1cbeab2018-02-21 17:32:26 +05303984 return "SLI/SLIX";
nxpandroidc7611652015-09-23 16:42:05 +05303985 case RW_I93_ICODE_SLI_S:
nxf24591c1cbeab2018-02-21 17:32:26 +05303986 return "SLI-S/SLIX-S";
nxpandroidc7611652015-09-23 16:42:05 +05303987 case RW_I93_ICODE_SLI_L:
nxf24591c1cbeab2018-02-21 17:32:26 +05303988 return "SLI-L/SLIX-L";
nxpandroidc7611652015-09-23 16:42:05 +05303989 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303990 return "Tag-it HF-I Plus Inlay";
nxpandroidc7611652015-09-23 16:42:05 +05303991 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
nxf24591c1cbeab2018-02-21 17:32:26 +05303992 return "Tag-it HF-I Plus Chip";
nxpandroidc7611652015-09-23 16:42:05 +05303993 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303994 return "Tag-it HF-I Standard Chip/Inlyas";
nxpandroidc7611652015-09-23 16:42:05 +05303995 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
nxf24591c1cbeab2018-02-21 17:32:26 +05303996 return "Tag-it HF-I Pro Chip/Inlays";
nxpandroidc7611652015-09-23 16:42:05 +05303997 case RW_I93_STM_LRI1K:
nxf24591c1cbeab2018-02-21 17:32:26 +05303998 return "LRi1K";
nxpandroidc7611652015-09-23 16:42:05 +05303999 case RW_I93_STM_LRI2K:
nxf24591c1cbeab2018-02-21 17:32:26 +05304000 return "LRi2K";
nxpandroidc7611652015-09-23 16:42:05 +05304001 case RW_I93_STM_LRIS2K:
nxf24591c1cbeab2018-02-21 17:32:26 +05304002 return "LRiS2K";
nxpandroidc7611652015-09-23 16:42:05 +05304003 case RW_I93_STM_LRIS64K:
nxf24591c1cbeab2018-02-21 17:32:26 +05304004 return "LRiS64K";
nxpandroidc7611652015-09-23 16:42:05 +05304005 case RW_I93_STM_M24LR64_R:
nxf24591c1cbeab2018-02-21 17:32:26 +05304006 return "M24LR64";
nxpandroidc7611652015-09-23 16:42:05 +05304007 case RW_I93_STM_M24LR04E_R:
nxf24591c1cbeab2018-02-21 17:32:26 +05304008 return "M24LR04E";
nxpandroidc7611652015-09-23 16:42:05 +05304009 case RW_I93_STM_M24LR16E_R:
nxf24591c1cbeab2018-02-21 17:32:26 +05304010 return "M24LR16E";
nxpandroidc7611652015-09-23 16:42:05 +05304011 case RW_I93_STM_M24LR64E_R:
nxf24591c1cbeab2018-02-21 17:32:26 +05304012 return "M24LR64E";
4013 case RW_I93_STM_ST25DV04K:
4014 return "ST25DV04";
4015 case RW_I93_STM_ST25DVHIK:
4016 return "ST25DV";
nxpandroidc7611652015-09-23 16:42:05 +05304017 case RW_I93_UNKNOWN_PRODUCT:
4018 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05304019 return "UNKNOWN";
nxpandroid8f6d0532017-07-12 18:25:30 +05304020 }
nxpandroidc7611652015-09-23 16:42:05 +05304021}