1 /******************************************************************************
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 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the implementation for ISO 15693 in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25 #include <string.h>
26
27 #include <android-base/stringprintf.h>
28 #include <base/logging.h>
29
30 #include "nfc_target.h"
31
32 #include "bt_types.h"
33 #include "nfc_api.h"
34 #include "nfc_int.h"
35 #include "rw_api.h"
36 #include "rw_int.h"
37 #include "trace_api.h"
38
39 using android::base::StringPrintf;
40
41 extern bool nfc_debug_enabled;
42
43 /* Response timeout */
44 #define RW_I93_TOUT_RESP 1000
45 /* 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
53
54 /* main state */
55 enum {
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 */
59
60 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 */
65
66 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
67 };
68
69 /* sub state */
70 enum {
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 */
76
77 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 */
80
81 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 */
85
86 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 */
89 };
90
91 static std::string rw_i93_get_state_name(uint8_t state);
92 static std::string rw_i93_get_sub_state_name(uint8_t sub_state);
93 static std::string rw_i93_get_tag_name(uint8_t product_version);
94
95 static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
96 tNFC_CONN* p_data);
97 void rw_i93_handle_error(tNFC_STATUS status);
98 tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
99 tNFC_STATUS rw_i93_send_cmd_get_ext_sys_info(uint8_t* p_uid);
100
101 /*******************************************************************************
102 **
103 ** Function rw_i93_get_product_version
104 **
105 ** Description Get product version from UID
106 **
107 ** Returns void
108 **
109 *******************************************************************************/
rw_i93_get_product_version(uint8_t * p_uid)110 void rw_i93_get_product_version(uint8_t* p_uid) {
111 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
112
113 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
114 return;
115 }
116
117 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
118
119 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
120
121 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;
128 else
129 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;
153 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;
157 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 }
178 }
179 } else {
180 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
181 }
182
183 DLOG_IF(INFO, nfc_debug_enabled)
184 << StringPrintf("product_version = <%s>",
185 rw_i93_get_tag_name(p_i93->product_version).c_str());
186
187 switch (p_i93->product_version) {
188 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
189 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
190 /* 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;
196 default:
197 break;
198 }
199 }
200
201 /*******************************************************************************
202 **
203 ** 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 *******************************************************************************/
rw_i93_process_ext_sys_info(uint8_t * p_data)210 bool 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 **
259 ** Function rw_i93_process_sys_info
260 **
261 ** Description Store system information of tag
262 **
263 ** Returns FALSE if retrying with protocol extension flag
264 **
265 *******************************************************************************/
rw_i93_process_sys_info(uint8_t * p_data)266 bool 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;
270
271 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
272
273 STREAM_TO_UINT8(p_i93->info_flags, p);
274
275 p_uid = uid;
276 STREAM_TO_ARRAY8(p_uid, p);
277
278 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);
289 }
290 /* it is one less than actual number of bytes */
291 p_i93->num_block += 1;
292
293 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);
299
300 /* clear existing UID to set product version */
301 p_i93->uid[0] = 0x00;
302
303 /* store UID and get product version */
304 rw_i93_get_product_version(p_uid);
305
306 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;
338 }
339 }
340 } 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;
345 } 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 }
354 }
355 }
356 }
357 }
358
359 return true;
360 }
361
362 /*******************************************************************************
363 **
364 ** Function rw_i93_check_sys_info_prot_ext
365 **
366 ** Description Check if need to set protocol extension flag to get system
367 ** info
368 **
369 ** Returns TRUE if sent Get System Info with protocol extension flag
370 **
371 *******************************************************************************/
rw_i93_check_sys_info_prot_ext(uint8_t error_code)372 bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
373 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
374
375 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
376
377 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 }
386 }
387
388 /*******************************************************************************
389 **
390 ** Function rw_i93_send_to_upper
391 **
392 ** Description Send response to upper layer
393 **
394 ** Returns void
395 **
396 *******************************************************************************/
rw_i93_send_to_upper(NFC_HDR * p_resp)397 void rw_i93_send_to_upper(NFC_HDR* p_resp) {
398 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
399 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;
405
406 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
407
408 STREAM_TO_UINT8(flags, p);
409 length--;
410
411 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);
422
423 rw_cb.tcb.i93.sent_cmd = 0;
424 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
425 }
426 return;
427 }
428
429 switch (p_i93->sent_cmd) {
430 case I93_CMD_INVENTORY:
431
432 /* forward inventory response */
433 rw_data.i93_inventory.status = NFC_STATUS_OK;
434 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
435
436 p_uid = rw_data.i93_inventory.uid;
437 STREAM_TO_ARRAY8(p_uid, p);
438
439 /* store UID and get product version */
440 rw_i93_get_product_version(p_uid);
441
442 event = RW_I93_INVENTORY_EVT;
443 break;
444
445 case I93_CMD_READ_SINGLE_BLOCK:
446 case I93_CMD_EXT_READ_SINGLE_BLOCK:
447 case I93_CMD_READ_MULTI_BLOCK:
448 case I93_CMD_EXT_READ_MULTI_BLOCK:
449 case I93_CMD_GET_MULTI_BLK_SEC:
450 case I93_CMD_EXT_GET_MULTI_BLK_SEC:
451
452 /* forward tag data or security status */
453 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
454
455 if (p_buff) {
456 p_buff->offset = 0;
457 p_buff->len = length;
458
459 memcpy((p_buff + 1), p, length);
460
461 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;
464
465 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;
470
471 event = RW_I93_CMD_CMPL_EVT;
472 }
473 break;
474
475 case I93_CMD_WRITE_SINGLE_BLOCK:
476 case I93_CMD_EXT_WRITE_SINGLE_BLOCK:
477 case I93_CMD_LOCK_BLOCK:
478 case I93_CMD_EXT_LOCK_BLOCK:
479 case I93_CMD_WRITE_MULTI_BLOCK:
480 case I93_CMD_EXT_WRITE_MULTI_BLOCK:
481 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
488 /* 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;
492
493 event = RW_I93_CMD_CMPL_EVT;
494 break;
495
496 case I93_CMD_GET_SYS_INFO:
497
498 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;
506
507 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
508
509 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;
516
517 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
539 default:
540 break;
541 }
542
543 rw_cb.tcb.i93.sent_cmd = 0;
544 if (event != RW_I93_MAX_EVT) {
545 (*(rw_cb.p_cback))(event, &rw_data);
546 } else {
547 LOG(ERROR) << StringPrintf("Invalid response");
548 }
549 }
550
551 /*******************************************************************************
552 **
553 ** Function rw_i93_send_to_lower
554 **
555 ** Description Send Request frame to lower layer
556 **
557 ** Returns TRUE if success
558 **
559 *******************************************************************************/
rw_i93_send_to_lower(NFC_HDR * p_msg)560 bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
561 /* 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 }
566
567 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
568
569 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 }
573
574 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
575 LOG(ERROR) << StringPrintf("failed");
576 return false;
577 }
578
579 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);
581
582 return true;
583 }
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 *******************************************************************************/
rw_i93_send_cmd_inventory(uint8_t * p_uid,bool including_afi,uint8_t afi)594 tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
595 uint8_t afi) {
596 NFC_HDR* p_cmd;
597 uint8_t *p, flags;
598
599 DLOG_IF(INFO, nfc_debug_enabled)
600 << StringPrintf("including_afi:%d, AFI:0x%02X", including_afi, afi);
601
602 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
603
604 if (!p_cmd) {
605 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
606 return NFC_STATUS_NO_BUFFERS;
607 }
608
609 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;
612
613 /* 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 }
619
620 UINT8_TO_STREAM(p, flags);
621
622 /* Command Code */
623 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
624
625 if (including_afi) {
626 /* Parameters */
627 UINT8_TO_STREAM(p, afi); /* Optional AFI */
628 p_cmd->len++;
629 }
630
631 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 }
638
639 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 }
645 }
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 *******************************************************************************/
rw_i93_send_cmd_stay_quiet(void)656 tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
657 NFC_HDR* p_cmd;
658 uint8_t* p;
659
660 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
661
662 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
663
664 if (!p_cmd) {
665 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
666 return NFC_STATUS_NO_BUFFERS;
667 }
668
669 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;
672
673 /* Flags */
674 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
675 RW_I93_FLAG_DATA_RATE));
676
677 /* Command Code */
678 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
679
680 /* Parameters */
681 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
682
683 if (rw_i93_send_to_lower(p_cmd)) {
684 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
685
686 /* 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 }
694 }
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 *******************************************************************************/
rw_i93_send_cmd_read_single_block(uint16_t block_number,bool read_security)705 tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
706 bool read_security) {
707 NFC_HDR* p_cmd;
708 uint8_t *p, flags;
709
710 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
711
712 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
713
714 if (!p_cmd) {
715 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
716 return NFC_STATUS_NO_BUFFERS;
717 }
718
719 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;
722
723 /* Flags */
724 flags =
725 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
726
727 if (read_security) flags |= I93_FLAG_OPTION_SET;
728
729 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
730 flags |= I93_FLAG_PROT_EXT_YES;
731
732 UINT8_TO_STREAM(p, flags);
733
734 /* Command Code */
735 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 }
740
741 /* Parameters */
742 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
743
744 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) {
746 UINT16_TO_STREAM(p, block_number); /* Block number */
747 p_cmd->len++;
748 } else {
749 UINT8_TO_STREAM(p, block_number); /* Block number */
750 }
751
752 if (rw_i93_send_to_lower(p_cmd)) {
753 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;
757 return NFC_STATUS_OK;
758 } else {
759 return NFC_STATUS_FAILED;
760 }
761 }
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 *******************************************************************************/
rw_i93_send_cmd_write_single_block(uint16_t block_number,uint8_t * p_data)772 tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
773 uint8_t* p_data) {
774 NFC_HDR* p_cmd;
775 uint8_t *p, flags;
776
777 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
778
779 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
780
781 if (!p_cmd) {
782 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
783 return NFC_STATUS_NO_BUFFERS;
784 }
785
786 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;
789
790 /* 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 }
802
803 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
804 flags |= I93_FLAG_PROT_EXT_YES;
805
806 UINT8_TO_STREAM(p, flags);
807
808 /* Command Code */
809 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 }
814
815 /* Parameters */
816 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
817
818 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) {
820 UINT16_TO_STREAM(p, block_number); /* Block number */
821 p_cmd->len++;
822 } else {
823 UINT8_TO_STREAM(p, block_number); /* Block number */
824 }
825
826 /* Data */
827 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
828
829 if (rw_i93_send_to_lower(p_cmd)) {
830 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;
834 return NFC_STATUS_OK;
835 } else {
836 return NFC_STATUS_FAILED;
837 }
838 }
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 *******************************************************************************/
rw_i93_send_cmd_lock_block(uint8_t block_number)852 tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
853 NFC_HDR* p_cmd;
854 uint8_t* p;
855
856 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
857
858 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
859
860 if (!p_cmd) {
861 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
862 return NFC_STATUS_NO_BUFFERS;
863 }
864
865 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;
868
869 /* 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 }
881
882 /* Command Code */
883 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 }
888
889 /* Parameters */
890 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
891
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 }
898
899 if (rw_i93_send_to_lower(p_cmd)) {
900 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;
904 return NFC_STATUS_OK;
905 } else {
906 return NFC_STATUS_FAILED;
907 }
908 }
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 *******************************************************************************/
rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,uint16_t number_blocks)919 tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
920 uint16_t number_blocks) {
921 NFC_HDR* p_cmd;
922 uint8_t *p, flags;
923
924 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
925
926 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
927
928 if (!p_cmd) {
929 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
930 return NFC_STATUS_NO_BUFFERS;
931 }
932
933 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;
936
937 /* Flags */
938 flags =
939 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
940
941 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
942 flags |= I93_FLAG_PROT_EXT_YES;
943 }
944
945 UINT8_TO_STREAM(p, flags);
946
947 /* Command Code */
948 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 }
953
954 /* Parameters */
955 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
956
957 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) {
959 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 }
964
965 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 }
973
974 if (rw_i93_send_to_lower(p_cmd)) {
975 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;
979 return NFC_STATUS_OK;
980 } else {
981 return NFC_STATUS_FAILED;
982 }
983 }
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 *******************************************************************************/
rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,uint16_t number_blocks,uint8_t * p_data)994 tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint16_t first_block_number,
995 uint16_t number_blocks,
996 uint8_t* p_data) {
997 NFC_HDR* p_cmd;
998 uint8_t* p;
999
1000 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1001
1002 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1003
1004 if (!p_cmd) {
1005 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1006 return NFC_STATUS_NO_BUFFERS;
1007 }
1008
1009 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;
1012
1013 /* Flags */
1014 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1015 RW_I93_FLAG_DATA_RATE));
1016
1017 /* Command Code */
1018 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 }
1023
1024 /* Parameters */
1025 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1026 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
1037 UINT8_TO_STREAM(
1038 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1039
1040 /* Data */
1041 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
1042
1043 if (rw_i93_send_to_lower(p_cmd)) {
1044 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;
1048 return NFC_STATUS_OK;
1049 } else {
1050 return NFC_STATUS_FAILED;
1051 }
1052 }
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 *******************************************************************************/
rw_i93_send_cmd_select(uint8_t * p_uid)1063 tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
1064 NFC_HDR* p_cmd;
1065 uint8_t* p;
1066
1067 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1068
1069 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1070
1071 if (!p_cmd) {
1072 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1073 return NFC_STATUS_NO_BUFFERS;
1074 }
1075
1076 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;
1079
1080 /* Flags */
1081 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1082 RW_I93_FLAG_DATA_RATE));
1083
1084 /* Command Code */
1085 UINT8_TO_STREAM(p, I93_CMD_SELECT);
1086
1087 /* Parameters */
1088 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1089
1090 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 }
1096 }
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 *******************************************************************************/
rw_i93_send_cmd_reset_to_ready(void)1107 tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
1108 NFC_HDR* p_cmd;
1109 uint8_t* p;
1110
1111 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1112
1113 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1114
1115 if (!p_cmd) {
1116 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1117 return NFC_STATUS_NO_BUFFERS;
1118 }
1119
1120 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;
1123
1124 /* Flags */
1125 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1126 RW_I93_FLAG_DATA_RATE));
1127
1128 /* Command Code */
1129 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
1130
1131 /* Parameters */
1132 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1133
1134 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 }
1140 }
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 *******************************************************************************/
rw_i93_send_cmd_write_afi(uint8_t afi)1151 tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1152 NFC_HDR* p_cmd;
1153 uint8_t* p;
1154
1155 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1156
1157 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1158
1159 if (!p_cmd) {
1160 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1161 return NFC_STATUS_NO_BUFFERS;
1162 }
1163
1164 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;
1167
1168 /* Flags */
1169 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1170 RW_I93_FLAG_DATA_RATE));
1171
1172 /* Command Code */
1173 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
1174
1175 /* Parameters */
1176 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1177 UINT8_TO_STREAM(p, afi); /* AFI */
1178
1179 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 }
1185 }
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 *******************************************************************************/
rw_i93_send_cmd_lock_afi(void)1196 tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1197 NFC_HDR* p_cmd;
1198 uint8_t* p;
1199
1200 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1201
1202 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1203
1204 if (!p_cmd) {
1205 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1206 return NFC_STATUS_NO_BUFFERS;
1207 }
1208
1209 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;
1212
1213 /* Flags */
1214 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1215 RW_I93_FLAG_DATA_RATE));
1216
1217 /* Command Code */
1218 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
1219
1220 /* Parameters */
1221 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1222
1223 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 }
1229 }
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 *******************************************************************************/
rw_i93_send_cmd_write_dsfid(uint8_t dsfid)1240 tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1241 NFC_HDR* p_cmd;
1242 uint8_t* p;
1243
1244 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1245
1246 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1247
1248 if (!p_cmd) {
1249 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1250 return NFC_STATUS_NO_BUFFERS;
1251 }
1252
1253 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;
1256
1257 /* Flags */
1258 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1259 RW_I93_FLAG_DATA_RATE));
1260
1261 /* Command Code */
1262 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
1263
1264 /* Parameters */
1265 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1266 UINT8_TO_STREAM(p, dsfid); /* DSFID */
1267
1268 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 }
1274 }
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 *******************************************************************************/
rw_i93_send_cmd_lock_dsfid(void)1285 tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1286 NFC_HDR* p_cmd;
1287 uint8_t* p;
1288
1289 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1290
1291 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1292
1293 if (!p_cmd) {
1294 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1295 return NFC_STATUS_NO_BUFFERS;
1296 }
1297
1298 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;
1301
1302 /* Flags */
1303 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1304 RW_I93_FLAG_DATA_RATE));
1305
1306 /* Command Code */
1307 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
1308
1309 /* Parameters */
1310 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1311
1312 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 }
1318 }
1319
1320 /*******************************************************************************
1321 **
1322 ** 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 *******************************************************************************/
rw_i93_send_cmd_get_ext_sys_info(uint8_t * p_uid)1329 tNFC_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 **
1375 ** 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 *******************************************************************************/
rw_i93_send_cmd_get_sys_info(uint8_t * p_uid,uint8_t extra_flags)1382 tNFC_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;
1385
1386 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1387
1388 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1389
1390 if (!p_cmd) {
1391 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1392 return NFC_STATUS_NO_BUFFERS;
1393 }
1394
1395 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;
1398
1399 /* Flags */
1400 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1401 RW_I93_FLAG_DATA_RATE | extra_flags));
1402
1403 /* Command Code */
1404 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
1405
1406 /* 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 }
1412
1413 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 }
1419 }
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 *******************************************************************************/
rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,uint16_t number_blocks)1430 tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1431 uint16_t number_blocks) {
1432 NFC_HDR* p_cmd;
1433 uint8_t *p, flags;
1434
1435 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1436
1437 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1438
1439 if (!p_cmd) {
1440 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
1441 return NFC_STATUS_NO_BUFFERS;
1442 }
1443
1444 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;
1447
1448 /* Flags */
1449 flags =
1450 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
1451
1452 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1453 flags |= I93_FLAG_PROT_EXT_YES;
1454
1455 UINT8_TO_STREAM(p, flags);
1456
1457 /* Command Code */
1458 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 }
1463
1464 /* Parameters */
1465 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1466
1467 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) {
1469 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 }
1478
1479 if (rw_i93_send_to_lower(p_cmd)) {
1480 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;
1484 return NFC_STATUS_OK;
1485 } else {
1486 return NFC_STATUS_FAILED;
1487 }
1488 }
1489
1490 /*******************************************************************************
1491 **
1492 ** Function rw_i93_get_next_blocks
1493 **
1494 ** Description Read as many blocks as possible (up to
1495 ** RW_I93_READ_MULTI_BLOCK_SIZE)
1496 **
1497 ** Returns tNFC_STATUS
1498 **
1499 *******************************************************************************/
rw_i93_get_next_blocks(uint16_t offset)1500 tNFC_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;
1504
1505 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1506
1507 first_block = offset / p_i93->block_size;
1508
1509 /* more blocks, more efficent but more error rate */
1510
1511 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1512 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
1513
1514 if (num_block + first_block > p_i93->num_block)
1515 num_block = p_i93->num_block - first_block;
1516
1517 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;
1530
1531 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);
1535 }
1536 }
1537 }
1538
1539 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 }
1543 }
1544
1545 /*******************************************************************************
1546 **
1547 ** Function rw_i93_get_next_block_sec
1548 **
1549 ** Description Get as many security of blocks as possible from
1550 ** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1551 **
1552 ** Returns tNFC_STATUS
1553 **
1554 *******************************************************************************/
rw_i93_get_next_block_sec(void)1555 tNFC_STATUS rw_i93_get_next_block_sec(void) {
1556 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1557 uint16_t num_blocks;
1558
1559 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1560
1561 if (p_i93->num_block <= p_i93->rw_offset) {
1562 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);
1565 return NFC_STATUS_FAILED;
1566 }
1567
1568 num_blocks = p_i93->num_block - p_i93->rw_offset;
1569
1570 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1571 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
1572
1573 DLOG_IF(INFO, nfc_debug_enabled)
1574 << __func__ << std::hex << rw_cb.tcb.i93.intl_flags;
1575 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
1576 }
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
1588 ** 5. Get block status to get max NDEF size and read-only
1589 ** status
1590 **
1591 ** Returns void
1592 **
1593 *******************************************************************************/
rw_i93_sm_detect_ndef(NFC_HDR * p_resp)1594 void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
1595 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
1596 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;
1601
1602 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);
1605
1606 STREAM_TO_UINT8(flags, p);
1607 length--;
1608
1609 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 {
1615 DLOG_IF(INFO, nfc_debug_enabled)
1616 << StringPrintf("Got error flags (0x%02x)", flags);
1617 rw_i93_handle_error(NFC_STATUS_FAILED);
1618 }
1619 return;
1620 }
1621
1622 switch (p_i93->sub_state) {
1623 case RW_I93_SUBSTATE_WAIT_UID:
1624
1625 STREAM_TO_UINT8(u8, p); /* DSFID */
1626 p_uid = p_i93->uid;
1627 STREAM_TO_ARRAY8(p_uid, p);
1628
1629 if (u8 != I93_DFS_UNSUPPORTED) {
1630 /* if Data Storage Format is unknown */
1631 DLOG_IF(INFO, nfc_debug_enabled)
1632 << StringPrintf("Got unknown DSFID (0x%02x)", u8);
1633 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);
1641 }
1642 }
1643 break;
1644
1645 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1646
1647 p_i93->block_size = 0;
1648 p_i93->num_block = 0;
1649
1650 if (!rw_i93_process_sys_info(p)) {
1651 /* retrying with protocol extension flag */
1652 break;
1653 }
1654
1655 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
1656 DLOG_IF(INFO, nfc_debug_enabled)
1657 << StringPrintf("Unable to get tag memory size");
1658 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;
1668
1669 case RW_I93_SUBSTATE_WAIT_CC:
1670
1671 /* assume block size is more than 4 */
1672 STREAM_TO_ARRAY(cc, p, 4);
1673
1674 status = NFC_STATUS_FAILED;
1675
1676 /*
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 */
1692
1693 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);
1698
1699 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER_E1) ||
1700 (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2)) {
1701 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 }
1712 if (cc[0] == I93_ICODE_CC_MAGIC_NUMER_E2) {
1713 p_i93->intl_flags |= RW_I93_FLAG_EXT_COMMANDS;
1714 }
1715 status = NFC_STATUS_OK;
1716 }
1717 }
1718
1719 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;
1724 else
1725 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);
1732 }
1733 } else {
1734 rw_i93_handle_error(NFC_STATUS_FAILED);
1735 }
1736 break;
1737
1738 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1739
1740 /* 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;
1751
1752 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 {
1758 DLOG_IF(INFO, nfc_debug_enabled)
1759 << StringPrintf("Invalid type: 0x%02x", *(p + xx));
1760 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;
1777 }
1778 }
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;
1789
1790 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 {
1802 /* read more data */
1803 p_i93->tlv_length -= (length - xx);
1804 break;
1805 }
1806 }
1807 }
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;
1850
1851 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1852
1853 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 */
1858
1859 block = (p_i93->rw_offset / p_i93->block_size);
1860 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1861
1862 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;
1870
1871 /* 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 }
1876 }
1877
1878 p_i93->max_ndef_length =
1879 p_i93->ndef_length
1880 /* add available bytes including the last block of NDEF TLV */
1881 + (p_i93->block_size * (block - last_block) + 1) -
1882 (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 */
1888 + p_i93->block_size -
1889 (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;
1894 }
1895
1896 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1897 num_blocks = length;
1898
1899 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 }
1915 }
1916
1917 /* update next security of block to check */
1918 p_i93->rw_offset += num_blocks;
1919
1920 /* 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 }
1928
1929 /* 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;
1936 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
1937 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
1954 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);
1957
1958 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
1959 break;
1960
1961 default:
1962 break;
1963 }
1964 }
1965
1966 /*******************************************************************************
1967 **
1968 ** Function rw_i93_sm_read_ndef
1969 **
1970 ** Description Process NDEF read procedure
1971 **
1972 ** Returns void
1973 **
1974 *******************************************************************************/
rw_i93_sm_read_ndef(NFC_HDR * p_resp)1975 void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
1976 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
1977 uint8_t flags;
1978 uint16_t offset, length = p_resp->len;
1979 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1980 tRW_DATA rw_data;
1981
1982 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1983
1984 STREAM_TO_UINT8(flags, p);
1985 length--;
1986
1987 if (flags & I93_FLAG_ERROR_DETECTED) {
1988 DLOG_IF(INFO, nfc_debug_enabled)
1989 << StringPrintf("Got error flags (0x%02x)", flags);
1990 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;
2003 }
2004
2005 /* 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 }
2011
2012 /* 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;
2017
2018 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
2035 DLOG_IF(INFO, nfc_debug_enabled)
2036 << StringPrintf("NDEF read complete read (%d)/total (%d)", p_resp->len,
2037 p_i93->ndef_length);
2038
2039 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2040 } else {
2041 DLOG_IF(INFO, nfc_debug_enabled)
2042 << StringPrintf("NDEF read segment read (%d)/total (%d)", p_resp->len,
2043 p_i93->ndef_length);
2044
2045 if (p_resp->len > 0) {
2046 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
2047 }
2048
2049 /* this will make read data from next block */
2050 p_i93->rw_offset += length;
2051
2052 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
2053 rw_i93_handle_error(NFC_STATUS_FAILED);
2054 }
2055 }
2056 }
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 *******************************************************************************/
rw_i93_sm_update_ndef(NFC_HDR * p_resp)2071 void 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;
2077
2078 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);
2081
2082 STREAM_TO_UINT8(flags, p);
2083 length--;
2084
2085 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 {
2093 DLOG_IF(INFO, nfc_debug_enabled)
2094 << StringPrintf("Got error flags (0x%02x)", flags);
2095 rw_i93_handle_error(NFC_STATUS_FAILED);
2096 return;
2097 }
2098 }
2099
2100 switch (p_i93->sub_state) {
2101 case RW_I93_SUBSTATE_RESET_LEN:
2102
2103 /* get offset of length field */
2104 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
2105
2106 /* set length to zero */
2107 *(p + length_offset) = 0x00;
2108
2109 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;
2115 }
2116
2117 /* 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 }
2126
2127 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;
2138
2139 case RW_I93_SUBSTATE_WRITE_NDEF:
2140
2141 /* 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;
2144
2145 /* 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;
2148
2149 p_i93->rw_offset += p_i93->block_size;
2150 p_i93->rw_length += p_i93->block_size;
2151
2152 /* 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));
2157
2158 /* 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;
2162
2163 /* 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;
2167 }
2168
2169 p_i93->ndef_tlv_last_offset =
2170 p_i93->rw_offset - p_i93->block_size + xx - 1;
2171 }
2172
2173 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;
2182
2183 /* 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;
2187
2188 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2189 NFC_STATUS_OK) {
2190 rw_i93_handle_error(NFC_STATUS_FAILED);
2191 }
2192 } 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 }
2217 }
2218 } 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;
2224
2225 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;
2229
2230 /* 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;
2237 }
2238
2239 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2240 break;
2241 }
2242 }
2243 rw_i93_handle_error(NFC_STATUS_FAILED);
2244 }
2245 break;
2246
2247 case RW_I93_SUBSTATE_UPDATE_LEN:
2248
2249 /* 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;
2255
2256 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;
2262
2263 /* 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);
2271
2272 p_i93->rw_length--;
2273 if (p_i93->rw_length == 0) break;
2274 }
2275
2276 block_number = (p_i93->rw_offset / p_i93->block_size);
2277
2278 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 }
2286 }
2287 } else {
2288 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);
2291
2292 p_i93->state = RW_I93_STATE_IDLE;
2293 p_i93->sent_cmd = 0;
2294 p_i93->p_update_data = NULL;
2295
2296 rw_data.status = NFC_STATUS_OK;
2297 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2298 }
2299 break;
2300
2301 default:
2302 break;
2303 }
2304 }
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 *******************************************************************************/
rw_i93_sm_format(NFC_HDR * p_resp)2320 void rw_i93_sm_format(NFC_HDR* p_resp) {
2321 uint8_t *p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
2322 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;
2327
2328 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);
2331
2332 STREAM_TO_UINT8(flags, p);
2333 length--;
2334
2335 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 {
2348 DLOG_IF(INFO, nfc_debug_enabled)
2349 << StringPrintf("Got error flags (0x%02x)", flags);
2350 rw_i93_handle_error(NFC_STATUS_FAILED);
2351 return;
2352 }
2353 }
2354
2355 switch (p_i93->sub_state) {
2356 case RW_I93_SUBSTATE_WAIT_UID:
2357
2358 p++; /* skip DSFID */
2359 p_uid = p_i93->uid;
2360 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
2361
2362 /* 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;
2370
2371 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2372
2373 p_i93->block_size = 0;
2374 p_i93->num_block = 0;
2375
2376 if (!rw_i93_process_sys_info(p)) {
2377 /* retrying with protocol extension flag */
2378 break;
2379 }
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)) {
2395 DLOG_IF(INFO, nfc_debug_enabled)
2396 << StringPrintf("Unable to get tag memory size");
2397 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;
2438
2439 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2440
2441 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 }
2446
2447 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);
2452 }
2453 } 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);
2458 }
2459 } 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 */
2464
2465 rw_cb.tcb.i93.rw_offset = 0;
2466
2467 /* 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;
2477
2478 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 }
2483 }
2484 }
2485 break;
2486
2487 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2488
2489 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;
2496 }
2497
2498 /* 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);
2506 break;
2507 }
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 }
2524 }
2525
2526 /* update block offset for read-only check */
2527 p_i93->rw_offset += length;
2528
2529 /* 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;
2535 }
2536 }
2537
2538 /* 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);
2540
2541 if (!p_i93->p_update_data) {
2542 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
2543 rw_i93_handle_error(NFC_STATUS_FAILED);
2544 break;
2545 }
2546
2547 p = p_i93->p_update_data;
2548
2549 /* Capability Container */
2550 *(p++) = I93_ICODE_CC_MAGIC_NUMER_E1; /* magic number */
2551 *(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;
2606
2607 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2608
2609 /* 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;
2613
2614 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);
2620 }
2621 } else {
2622 GKI_freebuf(p_i93->p_update_data);
2623 p_i93->p_update_data = NULL;
2624
2625 p_i93->state = RW_I93_STATE_IDLE;
2626 p_i93->sent_cmd = 0;
2627
2628 rw_data.status = NFC_STATUS_OK;
2629 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2630 }
2631 break;
2632
2633 default:
2634 break;
2635 }
2636 }
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 *******************************************************************************/
rw_i93_sm_set_read_only(NFC_HDR * p_resp)2651 void 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;
2657
2658 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);
2661
2662 STREAM_TO_UINT8(flags, p);
2663 length--;
2664
2665 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 {
2673 DLOG_IF(INFO, nfc_debug_enabled)
2674 << StringPrintf("Got error flags (0x%02x)", flags);
2675 rw_i93_handle_error(NFC_STATUS_FAILED);
2676 return;
2677 }
2678 }
2679
2680 switch (p_i93->sub_state) {
2681 case RW_I93_SUBSTATE_WAIT_CC:
2682
2683 /* mark CC as read-only */
2684 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
2685
2686 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;
2692
2693 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2694
2695 /* 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);
2698
2699 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;
2706
2707 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2708
2709 /* 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);
2713
2714 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);
2718 }
2719 }
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);
2727 }
2728 } 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;
2732
2733 rw_data.status = NFC_STATUS_OK;
2734 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2735 }
2736 break;
2737
2738 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2739
2740 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2741 p_i93->state = RW_I93_STATE_IDLE;
2742 p_i93->sent_cmd = 0;
2743
2744 rw_data.status = NFC_STATUS_OK;
2745 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2746 break;
2747
2748 default:
2749 break;
2750 }
2751 }
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 *******************************************************************************/
rw_i93_handle_error(tNFC_STATUS status)2762 void 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;
2766
2767 DLOG_IF(INFO, nfc_debug_enabled)
2768 << StringPrintf("status:0x%02X, state:0x%X", status, p_i93->state);
2769
2770 nfc_stop_quick_timer(&p_i93->timer);
2771
2772 if (rw_cb.p_cback) {
2773 rw_data.status = status;
2774
2775 switch (p_i93->state) {
2776 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2777 event = RW_I93_INTF_ERROR_EVT;
2778 break;
2779
2780 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;
2789 }
2790 break;
2791
2792 case RW_I93_STATE_DETECT_NDEF:
2793 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
2794 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;
2801
2802 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;
2815 }
2816 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;
2830 }
2831
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);
2837 }
2838 } else {
2839 p_i93->state = RW_I93_STATE_IDLE;
2840 }
2841 }
2842
2843 /*******************************************************************************
2844 **
2845 ** Function rw_i93_process_timeout
2846 **
2847 ** Description process timeout event
2848 **
2849 ** Returns none
2850 **
2851 *******************************************************************************/
rw_i93_process_timeout(TIMER_LIST_ENT * p_tle)2852 void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2853 NFC_HDR* p_buf;
2854
2855 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
2856
2857 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++;
2862 LOG(ERROR) << StringPrintf("retry_count = %d", rw_cb.tcb.i93.retry_count);
2863
2864 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2865 rw_cb.tcb.i93.p_retry_cmd = NULL;
2866
2867 if (rw_i93_send_to_lower(p_buf)) {
2868 return;
2869 }
2870 }
2871
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;
2877 }
2878 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
2879 } else {
2880 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
2881 }
2882 }
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 *******************************************************************************/
rw_i93_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2893 static void rw_i93_data_cback(__attribute__((unused)) uint8_t conn_id,
2894 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
2895 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2896 NFC_HDR* p_resp;
2897 tRW_DATA rw_data;
2898
2899 uint8_t begin_state = p_i93->state;
2900
2901 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
2902
2903 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
2904 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
2905 nfc_stop_quick_timer(&p_i93->timer);
2906
2907 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
2908 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
2909 p_i93->retry_count++;
2910
2911 LOG(ERROR) << StringPrintf("retry_count = %d", p_i93->retry_count);
2912
2913 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;
2917 }
2918 }
2919
2920 /* 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);
2923 p_i93->p_retry_cmd = NULL;
2924 p_i93->retry_count = 0;
2925 }
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;
2937 }
2938 return;
2939 }
2940
2941 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
2956 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);
2959
2960 switch (p_i93->state) {
2961 case RW_I93_STATE_IDLE:
2962 /* 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;
2974 case RW_I93_STATE_BUSY:
2975 p_i93->state = RW_I93_STATE_IDLE;
2976 rw_i93_send_to_upper(p_resp);
2977 GKI_freebuf(p_resp);
2978 break;
2979
2980 case RW_I93_STATE_DETECT_NDEF:
2981 rw_i93_sm_detect_ndef(p_resp);
2982 GKI_freebuf(p_resp);
2983 break;
2984
2985 case RW_I93_STATE_READ_NDEF:
2986 rw_i93_sm_read_ndef(p_resp);
2987 /* p_resp may send upper lyaer */
2988 break;
2989
2990 case RW_I93_STATE_UPDATE_NDEF:
2991 rw_i93_sm_update_ndef(p_resp);
2992 GKI_freebuf(p_resp);
2993 break;
2994
2995 case RW_I93_STATE_FORMAT:
2996 rw_i93_sm_format(p_resp);
2997 GKI_freebuf(p_resp);
2998 break;
2999
3000 case RW_I93_STATE_SET_READ_ONLY:
3001 rw_i93_sm_set_read_only(p_resp);
3002 GKI_freebuf(p_resp);
3003 break;
3004
3005 case RW_I93_STATE_PRESENCE_CHECK:
3006 p_i93->state = RW_I93_STATE_IDLE;
3007 p_i93->sent_cmd = 0;
3008
3009 /* 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;
3014
3015 default:
3016 LOG(ERROR) << StringPrintf("invalid state=%d", p_i93->state);
3017 GKI_freebuf(p_resp);
3018 break;
3019 }
3020
3021 if (begin_state != p_i93->state) {
3022 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());
3026 }
3027 }
3028
3029 /*******************************************************************************
3030 **
3031 ** Function rw_i93_select
3032 **
3033 ** Description Initialise ISO 15693 / T5T RW
3034 **
3035 ** Returns NFC_STATUS_OK if success
3036 **
3037 *******************************************************************************/
rw_i93_select(uint8_t * p_uid)3038 tNFC_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;
3041
3042 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3043
3044 NFC_SetStaticRfCback(rw_i93_data_cback);
3045
3046 p_i93->state = RW_I93_STATE_IDLE;
3047
3048 /* convert UID to big endian format - MSB(0xE0) in first byte */
3049 p = uid;
3050 STREAM_TO_ARRAY8(p, p_uid);
3051
3052 rw_i93_get_product_version(uid);
3053
3054 return NFC_STATUS_OK;
3055 }
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 *******************************************************************************/
RW_I93Inventory(bool including_afi,uint8_t afi,uint8_t * p_uid)3072 tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
3073 tNFC_STATUS status;
3074
3075 DLOG_IF(INFO, nfc_debug_enabled)
3076 << StringPrintf(", including_afi:%d, AFI:0x%02X", including_afi, afi);
3077
3078 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3079 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3080 rw_cb.tcb.i93.state);
3081 return NFC_STATUS_BUSY;
3082 }
3083
3084 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
3085
3086 if (status == NFC_STATUS_OK) {
3087 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3088 }
3089
3090 return (status);
3091 }
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 *******************************************************************************/
RW_I93StayQuiet(void)3107 tNFC_STATUS RW_I93StayQuiet(void) {
3108 tNFC_STATUS status;
3109
3110 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3111
3112 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3113 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3114 rw_cb.tcb.i93.state);
3115 return NFC_STATUS_BUSY;
3116 }
3117
3118 status = rw_i93_send_cmd_stay_quiet();
3119 if (status == NFC_STATUS_OK) {
3120 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3121 }
3122
3123 return status;
3124 }
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 *******************************************************************************/
RW_I93ReadSingleBlock(uint16_t block_number)3140 tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3141 tNFC_STATUS status;
3142
3143 DLOG_IF(INFO, nfc_debug_enabled)
3144 << StringPrintf("block_number:0x%02X", block_number);
3145
3146 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3147 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3148 rw_cb.tcb.i93.state);
3149 return NFC_STATUS_BUSY;
3150 }
3151
3152 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 }
3156
3157 return status;
3158 }
3159
3160 /*******************************************************************************
3161 **
3162 ** Function RW_I93WriteSingleBlock
3163 **
3164 ** Description This function send Write Single Block command
3165 ** Application must get block size first by calling
3166 ** RW_I93GetSysInfo().
3167 **
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 *******************************************************************************/
RW_I93WriteSingleBlock(uint16_t block_number,uint8_t * p_data)3176 tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3177 tNFC_STATUS status;
3178
3179 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3180
3181 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3182 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3183 rw_cb.tcb.i93.state);
3184 return NFC_STATUS_BUSY;
3185 }
3186
3187 if (rw_cb.tcb.i93.block_size == 0) {
3188 LOG(ERROR) << StringPrintf("Block size is unknown");
3189 return NFC_STATUS_FAILED;
3190 }
3191
3192 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 }
3196
3197 return status;
3198 }
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 *******************************************************************************/
RW_I93LockBlock(uint8_t block_number)3214 tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3215 tNFC_STATUS status;
3216
3217 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3218
3219 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3220 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3221 rw_cb.tcb.i93.state);
3222 return NFC_STATUS_BUSY;
3223 }
3224
3225 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 }
3229
3230 return status;
3231 }
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 *******************************************************************************/
RW_I93ReadMultipleBlocks(uint16_t first_block_number,uint16_t number_blocks)3247 tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3248 uint16_t number_blocks) {
3249 tNFC_STATUS status;
3250
3251 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3252
3253 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3254 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3255 rw_cb.tcb.i93.state);
3256 return NFC_STATUS_BUSY;
3257 }
3258
3259 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 }
3263
3264 return status;
3265 }
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 *******************************************************************************/
RW_I93WriteMultipleBlocks(uint16_t first_block_number,uint16_t number_blocks,uint8_t * p_data)3281 tNFC_STATUS RW_I93WriteMultipleBlocks(uint16_t first_block_number,
3282 uint16_t number_blocks, uint8_t* p_data) {
3283 tNFC_STATUS status;
3284
3285 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3286
3287 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3288 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3289 rw_cb.tcb.i93.state);
3290 return NFC_STATUS_BUSY;
3291 }
3292
3293 if (rw_cb.tcb.i93.block_size == 0) {
3294 LOG(ERROR) << StringPrintf("Block size is unknown");
3295 return NFC_STATUS_FAILED;
3296 }
3297
3298 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 }
3303
3304 return status;
3305 }
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 *******************************************************************************/
RW_I93Select(uint8_t * p_uid)3326 tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3327 tNFC_STATUS status;
3328
3329 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3330
3331 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3332 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3333 rw_cb.tcb.i93.state);
3334 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;
3341 }
3342 } else {
3343 LOG(ERROR) << StringPrintf("UID shall be provided");
3344 status = NFC_STATUS_FAILED;
3345 }
3346
3347 return status;
3348 }
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 *******************************************************************************/
RW_I93ResetToReady(void)3364 tNFC_STATUS RW_I93ResetToReady(void) {
3365 tNFC_STATUS status;
3366
3367 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3368
3369 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3370 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3371 rw_cb.tcb.i93.state);
3372 return NFC_STATUS_BUSY;
3373 }
3374
3375 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 }
3379
3380 return status;
3381 }
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 *******************************************************************************/
RW_I93WriteAFI(uint8_t afi)3397 tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3398 tNFC_STATUS status;
3399
3400 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3401
3402 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3403 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3404 rw_cb.tcb.i93.state);
3405 return NFC_STATUS_BUSY;
3406 }
3407
3408 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 }
3412
3413 return status;
3414 }
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 *******************************************************************************/
RW_I93LockAFI(void)3430 tNFC_STATUS RW_I93LockAFI(void) {
3431 tNFC_STATUS status;
3432
3433 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3434
3435 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3436 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3437 rw_cb.tcb.i93.state);
3438 return NFC_STATUS_BUSY;
3439 }
3440
3441 status = rw_i93_send_cmd_lock_afi();
3442 if (status == NFC_STATUS_OK) {
3443 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3444 }
3445
3446 return status;
3447 }
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 *******************************************************************************/
RW_I93WriteDSFID(uint8_t dsfid)3463 tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3464 tNFC_STATUS status;
3465
3466 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3467
3468 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3469 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3470 rw_cb.tcb.i93.state);
3471 return NFC_STATUS_BUSY;
3472 }
3473
3474 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 }
3478
3479 return status;
3480 }
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 *******************************************************************************/
RW_I93LockDSFID(void)3496 tNFC_STATUS RW_I93LockDSFID(void) {
3497 tNFC_STATUS status;
3498
3499 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3500
3501 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3502 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3503 rw_cb.tcb.i93.state);
3504 return NFC_STATUS_BUSY;
3505 }
3506
3507 status = rw_i93_send_cmd_lock_dsfid();
3508 if (status == NFC_STATUS_OK) {
3509 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3510 }
3511
3512 return status;
3513 }
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 *******************************************************************************/
RW_I93GetSysInfo(uint8_t * p_uid)3529 tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3530 tNFC_STATUS status;
3531
3532 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3533
3534 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3535 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3536 rw_cb.tcb.i93.state);
3537 return NFC_STATUS_BUSY;
3538 }
3539
3540 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 }
3545
3546 if (status == NFC_STATUS_OK) {
3547 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3548 }
3549
3550 return status;
3551 }
3552
3553 /*******************************************************************************
3554 **
3555 ** Function RW_I93GetMultiBlockSecurityStatus
3556 **
3557 ** Description This function send Get Multiple Block Security Status
3558 ** command
3559 **
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 *******************************************************************************/
RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,uint16_t number_blocks)3568 tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3569 uint16_t number_blocks) {
3570 tNFC_STATUS status;
3571
3572 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3573
3574 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3575 LOG(ERROR) << StringPrintf(
3576 "Unable to start command at state "
3577 "(0x%X)",
3578 rw_cb.tcb.i93.state);
3579 return NFC_STATUS_BUSY;
3580 }
3581
3582 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 }
3587
3588 return status;
3589 }
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 *******************************************************************************/
RW_I93DetectNDef(void)3603 tNFC_STATUS RW_I93DetectNDef(void) {
3604 tNFC_STATUS status;
3605 tRW_I93_RW_SUBSTATE sub_state;
3606
3607 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3608
3609 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3610 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3611 rw_cb.tcb.i93.state);
3612 return NFC_STATUS_FAILED;
3613 }
3614
3615 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;
3623
3624 /* 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 }
3631
3632 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;
3635
3636 /* 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 }
3639
3640 return (status);
3641 }
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
3652 ** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3653 ** complete NDEF
3654 ** 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 *******************************************************************************/
RW_I93ReadNDef(void)3660 tNFC_STATUS RW_I93ReadNDef(void) {
3661 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3662
3663 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3664 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3665 rw_cb.tcb.i93.state);
3666 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;
3678 }
3679 } else {
3680 LOG(ERROR) << StringPrintf("No NDEF detected");
3681 return NFC_STATUS_FAILED;
3682 }
3683
3684 return NFC_STATUS_OK;
3685 }
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
3693 ** Updating data must not be removed until returning
3694 ** event
3695 **
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 *******************************************************************************/
RW_I93UpdateNDef(uint16_t length,uint8_t * p_data)3704 tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3705 uint16_t block_number;
3706
3707 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
3708
3709 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3710 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3711 rw_cb.tcb.i93.state);
3712 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) {
3717 LOG(ERROR) << StringPrintf("NDEF is read-only");
3718 return NFC_STATUS_FAILED;
3719 }
3720 if (rw_cb.tcb.i93.max_ndef_length < length) {
3721 LOG(ERROR) << StringPrintf(
3722 "data (%d bytes) is more than max NDEF length "
3723 "(%d)",
3724 length, rw_cb.tcb.i93.max_ndef_length);
3725 return NFC_STATUS_FAILED;
3726 }
3727
3728 rw_cb.tcb.i93.ndef_length = length;
3729 rw_cb.tcb.i93.p_update_data = p_data;
3730
3731 /* 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;
3734
3735 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
3736
3737 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;
3743 }
3744 } else {
3745 LOG(ERROR) << StringPrintf("No NDEF detected");
3746 return NFC_STATUS_FAILED;
3747 }
3748
3749 return NFC_STATUS_OK;
3750 }
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 *******************************************************************************/
RW_I93FormatNDef(void)3764 tNFC_STATUS RW_I93FormatNDef(void) {
3765 tNFC_STATUS status;
3766 tRW_I93_RW_SUBSTATE sub_state;
3767
3768 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3769
3770 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3771 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3772 rw_cb.tcb.i93.state);
3773 return NFC_STATUS_FAILED;
3774 }
3775
3776 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;
3781
3782 /* 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 }
3789
3790 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 }
3795
3796 return (status);
3797 }
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
3805 ** Updating data must not be removed until returning
3806 ** event
3807 **
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 *******************************************************************************/
RW_I93SetTagReadOnly(void)3814 tNFC_STATUS RW_I93SetTagReadOnly(void) {
3815 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3816
3817 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3818 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
3819 rw_cb.tcb.i93.state);
3820 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) {
3825 LOG(ERROR) << StringPrintf("NDEF is already read-only");
3826 return NFC_STATUS_FAILED;
3827 }
3828
3829 /* 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;
3835 }
3836 } else {
3837 LOG(ERROR) << StringPrintf("No NDEF detected");
3838 return NFC_STATUS_FAILED;
3839 }
3840
3841 return NFC_STATUS_OK;
3842 }
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
3854 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3855 ** operation
3856 ** NFC_STATUS_FAILED: other error
3857 **
3858 *****************************************************************************/
RW_I93PresenceCheck(void)3859 tNFC_STATUS RW_I93PresenceCheck(void) {
3860 tNFC_STATUS status;
3861 tRW_DATA evt_data;
3862
3863 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
3864
3865 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);
3870
3871 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;
3882 }
3883 }
3884
3885 return (status);
3886 }
3887
3888 /*******************************************************************************
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 *******************************************************************************/
rw_i93_get_state_name(uint8_t state)3899 static std::string rw_i93_get_state_name(uint8_t state) {
3900 switch (state) {
3901 case RW_I93_STATE_NOT_ACTIVATED:
3902 return "NOT_ACTIVATED";
3903 case RW_I93_STATE_IDLE:
3904 return "IDLE";
3905 case RW_I93_STATE_BUSY:
3906 return "BUSY";
3907 case RW_I93_STATE_DETECT_NDEF:
3908 return "NDEF_DETECTION";
3909 case RW_I93_STATE_READ_NDEF:
3910 return "READ_NDEF";
3911 case RW_I93_STATE_UPDATE_NDEF:
3912 return "UPDATE_NDEF";
3913 case RW_I93_STATE_FORMAT:
3914 return "FORMAT";
3915 case RW_I93_STATE_SET_READ_ONLY:
3916 return "SET_READ_ONLY";
3917 case RW_I93_STATE_PRESENCE_CHECK:
3918 return "PRESENCE_CHECK";
3919 default:
3920 return "???? UNKNOWN STATE";
3921 }
3922 }
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 *******************************************************************************/
rw_i93_get_sub_state_name(uint8_t sub_state)3935 static std::string rw_i93_get_sub_state_name(uint8_t sub_state) {
3936 switch (sub_state) {
3937 case RW_I93_SUBSTATE_WAIT_UID:
3938 return "WAIT_UID";
3939 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
3940 return "WAIT_SYS_INFO";
3941 case RW_I93_SUBSTATE_WAIT_CC:
3942 return "WAIT_CC";
3943 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
3944 return "SEARCH_NDEF_TLV";
3945 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
3946 return "CHECK_LOCK_STATUS";
3947 case RW_I93_SUBSTATE_RESET_LEN:
3948 return "RESET_LEN";
3949 case RW_I93_SUBSTATE_WRITE_NDEF:
3950 return "WRITE_NDEF";
3951 case RW_I93_SUBSTATE_UPDATE_LEN:
3952 return "UPDATE_LEN";
3953 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
3954 return "WAIT_RESET_DSFID_AFI";
3955 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
3956 return "CHECK_READ_ONLY";
3957 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
3958 return "WRITE_CC_NDEF_TLV";
3959 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
3960 return "WAIT_UPDATE_CC";
3961 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
3962 return "LOCK_NDEF_TLV";
3963 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
3964 return "WAIT_LOCK_CC";
3965 default:
3966 return "???? UNKNOWN SUBSTATE";
3967 }
3968 }
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 *******************************************************************************/
rw_i93_get_tag_name(uint8_t product_version)3981 static std::string rw_i93_get_tag_name(uint8_t product_version) {
3982 switch (product_version) {
3983 case RW_I93_ICODE_SLI:
3984 return "SLI/SLIX";
3985 case RW_I93_ICODE_SLI_S:
3986 return "SLI-S/SLIX-S";
3987 case RW_I93_ICODE_SLI_L:
3988 return "SLI-L/SLIX-L";
3989 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
3990 return "Tag-it HF-I Plus Inlay";
3991 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
3992 return "Tag-it HF-I Plus Chip";
3993 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
3994 return "Tag-it HF-I Standard Chip/Inlyas";
3995 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
3996 return "Tag-it HF-I Pro Chip/Inlays";
3997 case RW_I93_STM_LRI1K:
3998 return "LRi1K";
3999 case RW_I93_STM_LRI2K:
4000 return "LRi2K";
4001 case RW_I93_STM_LRIS2K:
4002 return "LRiS2K";
4003 case RW_I93_STM_LRIS64K:
4004 return "LRiS64K";
4005 case RW_I93_STM_M24LR64_R:
4006 return "M24LR64";
4007 case RW_I93_STM_M24LR04E_R:
4008 return "M24LR04E";
4009 case RW_I93_STM_M24LR16E_R:
4010 return "M24LR16E";
4011 case RW_I93_STM_M24LR64E_R:
4012 return "M24LR64E";
4013 case RW_I93_STM_ST25DV04K:
4014 return "ST25DV04";
4015 case RW_I93_STM_ST25DVHIK:
4016 return "ST25DV";
4017 case RW_I93_UNKNOWN_PRODUCT:
4018 default:
4019 return "UNKNOWN";
4020 }
4021 }
4022