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 <log/log.h>
26 #include <string.h>
27 #include "bt_types.h"
28 #include "nfc_target.h"
29 #include "trace_api.h"
30
31 #include "nfc_api.h"
32 #include "nfc_int.h"
33 #include "rw_api.h"
34 #include "rw_int.h"
35
36 /* Response timeout */
37 #define RW_I93_TOUT_RESP 1000
38 /* stay quiet timeout */
39 #define RW_I93_TOUT_STAY_QUIET 200
40 /* max reading data if read multi block is supported */
41 #define RW_I93_READ_MULTI_BLOCK_SIZE 128
42 /* CC, zero length NDEF, Terminator TLV */
43 #define RW_I93_FORMAT_DATA_LEN 8
44 /* max getting lock status if get multi block sec is supported */
45 #define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
46 /*Capability Container CC Size */
47 #define RW_I93_CC_SIZE 4
48
49 /* main state */
50 enum {
51 RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
52 RW_I93_STATE_IDLE, /* waiting for upper layer API */
53 RW_I93_STATE_BUSY, /* waiting for response from tag */
54
55 RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
56 RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
57 RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
58 RW_I93_STATE_FORMAT, /* performing format procedure */
59 RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
60
61 RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
62 };
63
64 /* sub state */
65 enum {
66 RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
67 RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
68 RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
69 RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
70 RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
71
72 RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
73 RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
74 RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
75
76 RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
77 RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
78 RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
79 */
80
81 RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
82 RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
83 RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
84 };
85
86 #if (BT_TRACE_VERBOSE == TRUE)
87 static char* rw_i93_get_state_name(uint8_t state);
88 static char* rw_i93_get_sub_state_name(uint8_t sub_state);
89 static char* rw_i93_get_tag_name(uint8_t product_version);
90 #endif
91
92 static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
93 tNFC_CONN* p_data);
94 void rw_i93_handle_error(tNFC_STATUS status);
95 tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
96
97 /*******************************************************************************
98 **
99 ** Function rw_i93_get_product_version
100 **
101 ** Description Get product version from UID
102 **
103 ** Returns void
104 **
105 *******************************************************************************/
rw_i93_get_product_version(uint8_t * p_uid)106 void rw_i93_get_product_version(uint8_t* p_uid) {
107 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
108
109 if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
110 return;
111 }
112
113 RW_TRACE_DEBUG0("rw_i93_get_product_version ()");
114
115 memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
116
117 if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
118 if (p_uid[2] == I93_UID_ICODE_SLI)
119 p_i93->product_version = RW_I93_ICODE_SLI;
120 else if (p_uid[2] == I93_UID_ICODE_SLI_S)
121 p_i93->product_version = RW_I93_ICODE_SLI_S;
122 else if (p_uid[2] == I93_UID_ICODE_SLI_L)
123 p_i93->product_version = RW_I93_ICODE_SLI_L;
124 else
125 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
126 } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
127 if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
128 I93_UID_TAG_IT_HF_I_PLUS_INLAY)
129 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
130 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
131 I93_UID_TAG_IT_HF_I_PLUS_CHIP)
132 p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
133 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
134 I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
135 p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
136 else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
137 I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
138 p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
139 else
140 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
141 } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
142 (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
143 if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
144 p_i93->product_version = RW_I93_STM_M24LR04E_R;
145 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
146 p_i93->product_version = RW_I93_STM_M24LR16E_R;
147 else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
148 p_i93->product_version = RW_I93_STM_M24LR64E_R;
149 else {
150 switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
151 case I93_IC_REF_STM_LRI1K:
152 p_i93->product_version = RW_I93_STM_LRI1K;
153 break;
154 case I93_IC_REF_STM_LRI2K:
155 p_i93->product_version = RW_I93_STM_LRI2K;
156 break;
157 case I93_IC_REF_STM_LRIS2K:
158 p_i93->product_version = RW_I93_STM_LRIS2K;
159 break;
160 case I93_IC_REF_STM_LRIS64K:
161 p_i93->product_version = RW_I93_STM_LRIS64K;
162 break;
163 case I93_IC_REF_STM_M24LR64_R:
164 p_i93->product_version = RW_I93_STM_M24LR64_R;
165 break;
166 default:
167 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
168 break;
169 }
170 }
171 } else {
172 p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
173 }
174
175 #if (BT_TRACE_VERBOSE == TRUE)
176 RW_TRACE_DEBUG1("product_version = <%s>",
177 rw_i93_get_tag_name(p_i93->product_version));
178 #else
179 RW_TRACE_DEBUG1("product_version = %d", p_i93->product_version);
180 #endif
181
182 switch (p_i93->product_version) {
183 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
184 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
185 /* these don't support Get System Information Command */
186 /* these support only Inventory, Stay Quiet, Read Single Block, Write
187 * Single Block, Lock Block */
188 p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
189 p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
190 break;
191 default:
192 break;
193 }
194 }
195
196 /*******************************************************************************
197 **
198 ** Function rw_i93_process_sys_info
199 **
200 ** Description Store system information of tag
201 **
202 ** Returns FALSE if retrying with protocol extension flag
203 **
204 *******************************************************************************/
rw_i93_process_sys_info(uint8_t * p_data,uint16_t length)205 bool rw_i93_process_sys_info(uint8_t* p_data, uint16_t length) {
206 uint8_t* p = p_data;
207 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
208 uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
209
210 RW_TRACE_DEBUG0("rw_i93_process_sys_info ()");
211
212 if (length < (I93_UID_BYTE_LEN + 1)) {
213 android_errorWriteLog(0x534e4554, "121259048");
214 return false;
215 }
216 STREAM_TO_UINT8(p_i93->info_flags, p);
217 length--;
218
219 p_uid = uid;
220 STREAM_TO_ARRAY8(p_uid, p);
221 length -= I93_UID_BYTE_LEN;
222
223 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
224 if (length == 0) {
225 android_errorWriteLog(0x534e4554, "121259048");
226 return false;
227 }
228 STREAM_TO_UINT8(p_i93->dsfid, p);
229 length--;
230 }
231 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
232 if (length == 0) {
233 android_errorWriteLog(0x534e4554, "121259048");
234 return false;
235 }
236 STREAM_TO_UINT8(p_i93->afi, p);
237 length--;
238 }
239 if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
240 bool block_16_bit = p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK;
241 if (block_16_bit && length > 2) {
242 STREAM_TO_UINT16(p_i93->num_block, p);
243 length -= 2;
244 } else if (!block_16_bit && length > 1) {
245 STREAM_TO_UINT8(p_i93->num_block, p);
246 length--;
247 } else {
248 android_errorWriteLog(0x534e4554, "121259048");
249 return false;
250 }
251 /* it is one less than actual number of bytes */
252 p_i93->num_block += 1;
253
254 STREAM_TO_UINT8(p_i93->block_size, p);
255 length--;
256 /* it is one less than actual number of blocks */
257 p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
258 }
259 if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
260 if (length == 0) {
261 android_errorWriteLog(0x534e4554, "121259048");
262 return false;
263 }
264 STREAM_TO_UINT8(p_i93->ic_reference, p);
265
266 /* clear existing UID to set product version */
267 p_i93->uid[0] = 0x00;
268
269 /* store UID and get product version */
270 rw_i93_get_product_version(p_uid);
271
272 if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
273 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
274 (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
275 p_i93->num_block = 8;
276 p_i93->block_size = 4;
277 } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
278 /*
279 ** LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20
280 ** LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40
281 ** LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40
282 ** LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800
283 ** M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800
284 ** M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
285 ** M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
286 ** M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
287 */
288 if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
289 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
290 /*
291 ** M24LR16E-R or M24LR64E-R returns system information
292 ** without memory size, if option flag is not set.
293 ** LRIS64K and M24LR64-R return error if option flag is not
294 ** set.
295 */
296 if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
297 /* get memory size with protocol extension flag */
298 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
299 NFC_STATUS_OK) {
300 /* STM supports more than 2040 bytes */
301 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
302
303 return false;
304 }
305 }
306 return true;
307 } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
308 (p_i93->ic_reference == 0x21)) {
309 /* workaround of byte order in memory size information */
310 p_i93->num_block = 64;
311 p_i93->block_size = 4;
312 }
313 }
314 }
315 }
316
317 return true;
318 }
319
320 /*******************************************************************************
321 **
322 ** Function rw_i93_check_sys_info_prot_ext
323 **
324 ** Description Check if need to set protocol extension flag to get system
325 ** info
326 **
327 ** Returns TRUE if sent Get System Info with protocol extension flag
328 **
329 *******************************************************************************/
rw_i93_check_sys_info_prot_ext(uint8_t error_code)330 bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
331 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
332
333 RW_TRACE_DEBUG0("rw_i93_check_sys_info_prot_ext ()");
334
335 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
336 (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
337 (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
338 (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
339 NFC_STATUS_OK)) {
340 return true;
341 } else {
342 return false;
343 }
344 }
345
346 /*******************************************************************************
347 **
348 ** Function rw_i93_send_to_upper
349 **
350 ** Description Send response to upper layer
351 **
352 ** Returns void
353 **
354 *******************************************************************************/
rw_i93_send_to_upper(NFC_HDR * p_resp)355 void rw_i93_send_to_upper(NFC_HDR* p_resp) {
356 uint8_t *p = (uint8_t *)(p_resp + 1) + p_resp->offset, *p_uid;
357 uint16_t length = p_resp->len;
358 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
359 tRW_DATA rw_data;
360 uint8_t event = RW_I93_MAX_EVT;
361 uint8_t flags;
362 NFC_HDR* p_buff;
363
364 RW_TRACE_DEBUG0("rw_i93_send_to_upper ()");
365
366 STREAM_TO_UINT8(flags, p);
367 length--;
368
369 if (flags & I93_FLAG_ERROR_DETECTED) {
370 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
371 /* getting system info with protocol extension flag */
372 /* This STM tag supports more than 2040 bytes */
373 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
374 p_i93->state = RW_I93_STATE_BUSY;
375 } else {
376 /* notify error to upper layer */
377 rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
378 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
379 STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
380
381 rw_cb.tcb.i93.sent_cmd = 0;
382 (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
383 }
384 return;
385 }
386
387 switch (p_i93->sent_cmd) {
388 case I93_CMD_INVENTORY:
389
390 /* forward inventory response */
391 rw_data.i93_inventory.status = NFC_STATUS_OK;
392 STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
393
394 p_uid = rw_data.i93_inventory.uid;
395 STREAM_TO_ARRAY8(p_uid, p);
396
397 /* store UID and get product version */
398 rw_i93_get_product_version(p_uid);
399
400 event = RW_I93_INVENTORY_EVT;
401 break;
402
403 case I93_CMD_READ_SINGLE_BLOCK:
404 case I93_CMD_READ_MULTI_BLOCK:
405 case I93_CMD_GET_MULTI_BLK_SEC:
406
407 /* forward tag data or security status */
408 p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
409
410 if (p_buff) {
411 p_buff->offset = 0;
412 p_buff->len = length;
413
414 memcpy((p_buff + 1), p, length);
415
416 rw_data.i93_data.status = NFC_STATUS_OK;
417 rw_data.i93_data.command = p_i93->sent_cmd;
418 rw_data.i93_data.p_data = p_buff;
419
420 event = RW_I93_DATA_EVT;
421 } else {
422 rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
423 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
424 rw_data.i93_cmd_cmpl.error_code = 0;
425
426 event = RW_I93_CMD_CMPL_EVT;
427 }
428 break;
429
430 case I93_CMD_WRITE_SINGLE_BLOCK:
431 case I93_CMD_LOCK_BLOCK:
432 case I93_CMD_WRITE_MULTI_BLOCK:
433 case I93_CMD_SELECT:
434 case I93_CMD_RESET_TO_READY:
435 case I93_CMD_WRITE_AFI:
436 case I93_CMD_LOCK_AFI:
437 case I93_CMD_WRITE_DSFID:
438 case I93_CMD_LOCK_DSFID:
439
440 /* notify the complete of command */
441 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
442 rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
443 rw_data.i93_cmd_cmpl.error_code = 0;
444
445 event = RW_I93_CMD_CMPL_EVT;
446 break;
447
448 case I93_CMD_GET_SYS_INFO:
449
450 if (rw_i93_process_sys_info(p, length)) {
451 rw_data.i93_sys_info.status = NFC_STATUS_OK;
452 rw_data.i93_sys_info.info_flags = p_i93->info_flags;
453 rw_data.i93_sys_info.dsfid = p_i93->dsfid;
454 rw_data.i93_sys_info.afi = p_i93->afi;
455 rw_data.i93_sys_info.num_block = p_i93->num_block;
456 rw_data.i93_sys_info.block_size = p_i93->block_size;
457 rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
458
459 memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
460
461 event = RW_I93_SYS_INFO_EVT;
462 } else {
463 /* retrying with protocol extension flag */
464 p_i93->state = RW_I93_STATE_BUSY;
465 return;
466 }
467 break;
468
469 default:
470 break;
471 }
472
473 rw_cb.tcb.i93.sent_cmd = 0;
474 if (event != RW_I93_MAX_EVT) {
475 (*(rw_cb.p_cback))(event, &rw_data);
476 } else {
477 RW_TRACE_ERROR0("rw_i93_send_to_upper (): Invalid response");
478 }
479 }
480
481 /*******************************************************************************
482 **
483 ** Function rw_i93_send_to_lower
484 **
485 ** Description Send Request frame to lower layer
486 **
487 ** Returns TRUE if success
488 **
489 *******************************************************************************/
rw_i93_send_to_lower(NFC_HDR * p_msg)490 bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
491 #if (BT_TRACE_PROTOCOL == TRUE)
492 DispRWI93Tag(p_msg, false, 0x00);
493 #endif
494
495 /* store command for retransmitting */
496 if (rw_cb.tcb.i93.p_retry_cmd) {
497 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
498 rw_cb.tcb.i93.p_retry_cmd = NULL;
499 }
500
501 rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
502
503 if (rw_cb.tcb.i93.p_retry_cmd) {
504 memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
505 sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
506 }
507
508 if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
509 RW_TRACE_ERROR0("rw_i93_send_to_lower (): NFC_SendData () failed");
510 return false;
511 }
512
513 nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
514 (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
515
516 return true;
517 }
518
519 /*******************************************************************************
520 **
521 ** Function rw_i93_send_cmd_inventory
522 **
523 ** Description Send Inventory Request to VICC
524 **
525 ** Returns tNFC_STATUS
526 **
527 *******************************************************************************/
rw_i93_send_cmd_inventory(uint8_t * p_uid,bool including_afi,uint8_t afi)528 tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
529 uint8_t afi) {
530 NFC_HDR* p_cmd;
531 uint8_t *p, flags;
532
533 RW_TRACE_DEBUG2("rw_i93_send_cmd_inventory () including_afi:%d, AFI:0x%02X",
534 including_afi, afi);
535
536 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
537
538 if (!p_cmd) {
539 RW_TRACE_ERROR0("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
540 return NFC_STATUS_NO_BUFFERS;
541 }
542
543 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
544 p_cmd->len = 3;
545 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
546
547 /* Flags */
548 flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
549 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
550 if (including_afi) {
551 flags |= I93_FLAG_AFI_PRESENT;
552 }
553
554 UINT8_TO_STREAM(p, flags);
555
556 /* Command Code */
557 UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
558
559 if (including_afi) {
560 /* Parameters */
561 UINT8_TO_STREAM(p, afi); /* Optional AFI */
562 p_cmd->len++;
563 }
564
565 if (p_uid) {
566 UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
567 ARRAY8_TO_STREAM(p, p_uid); /* UID */
568 p_cmd->len += I93_UID_BYTE_LEN;
569 } else {
570 UINT8_TO_STREAM(p, 0x00); /* Mask Length */
571 }
572
573 if (rw_i93_send_to_lower(p_cmd)) {
574 rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
575 return NFC_STATUS_OK;
576 } else {
577 return NFC_STATUS_FAILED;
578 }
579 }
580
581 /*******************************************************************************
582 **
583 ** Function rw_i93_send_cmd_stay_quiet
584 **
585 ** Description Send Stay Quiet Request to VICC
586 **
587 ** Returns tNFC_STATUS
588 **
589 *******************************************************************************/
rw_i93_send_cmd_stay_quiet(void)590 tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
591 NFC_HDR* p_cmd;
592 uint8_t* p;
593
594 RW_TRACE_DEBUG0("rw_i93_send_cmd_stay_quiet ()");
595
596 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
597
598 if (!p_cmd) {
599 RW_TRACE_ERROR0("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
600 return NFC_STATUS_NO_BUFFERS;
601 }
602
603 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
604 p_cmd->len = 10;
605 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
606
607 /* Flags */
608 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
609 RW_I93_FLAG_DATA_RATE));
610
611 /* Command Code */
612 UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
613
614 /* Parameters */
615 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
616
617 if (rw_i93_send_to_lower(p_cmd)) {
618 rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
619
620 /* restart timer for stay quiet */
621 nfc_start_quick_timer(
622 &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
623 (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
624 return NFC_STATUS_OK;
625 } else {
626 return NFC_STATUS_FAILED;
627 }
628 }
629
630 /*******************************************************************************
631 **
632 ** Function rw_i93_send_cmd_read_single_block
633 **
634 ** Description Send Read Single Block Request to VICC
635 **
636 ** Returns tNFC_STATUS
637 **
638 *******************************************************************************/
rw_i93_send_cmd_read_single_block(uint16_t block_number,bool read_security)639 tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
640 bool read_security) {
641 NFC_HDR* p_cmd;
642 uint8_t *p, flags;
643
644 RW_TRACE_DEBUG0("rw_i93_send_cmd_read_single_block ()");
645
646 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
647
648 if (!p_cmd) {
649 RW_TRACE_ERROR0(
650 "rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
651 return NFC_STATUS_NO_BUFFERS;
652 }
653
654 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
655 p_cmd->len = 11;
656 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
657
658 /* Flags */
659 flags =
660 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
661
662 if (read_security) flags |= I93_FLAG_OPTION_SET;
663
664 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
665 flags |= I93_FLAG_PROT_EXT_YES;
666
667 UINT8_TO_STREAM(p, flags);
668
669 /* Command Code */
670 UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
671
672 /* Parameters */
673 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
674
675 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
676 UINT16_TO_STREAM(p, block_number); /* Block number */
677 p_cmd->len++;
678 } else {
679 UINT8_TO_STREAM(p, block_number); /* Block number */
680 }
681
682 if (rw_i93_send_to_lower(p_cmd)) {
683 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
684 return NFC_STATUS_OK;
685 } else {
686 return NFC_STATUS_FAILED;
687 }
688 }
689
690 /*******************************************************************************
691 **
692 ** Function rw_i93_send_cmd_write_single_block
693 **
694 ** Description Send Write Single Block Request to VICC
695 **
696 ** Returns tNFC_STATUS
697 **
698 *******************************************************************************/
rw_i93_send_cmd_write_single_block(uint16_t block_number,uint8_t * p_data)699 tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
700 uint8_t* p_data) {
701 NFC_HDR* p_cmd;
702 uint8_t *p, flags;
703
704 RW_TRACE_DEBUG0("rw_i93_send_cmd_write_single_block ()");
705
706 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
707
708 if (!p_cmd) {
709 RW_TRACE_ERROR0(
710 "rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
711 return NFC_STATUS_NO_BUFFERS;
712 }
713
714 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
715 p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
716 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
717
718 /* Flags */
719 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
720 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
721 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
722 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
723 /* Option must be set for TI tag */
724 flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
725 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
726 } else {
727 flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
728 RW_I93_FLAG_DATA_RATE);
729 }
730
731 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
732 flags |= I93_FLAG_PROT_EXT_YES;
733
734 UINT8_TO_STREAM(p, flags);
735
736 /* Command Code */
737 UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
738
739 /* Parameters */
740 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
741
742 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
743 UINT16_TO_STREAM(p, block_number); /* Block number */
744 p_cmd->len++;
745 } else {
746 UINT8_TO_STREAM(p, block_number); /* Block number */
747 }
748
749 /* Data */
750 ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
751
752 if (rw_i93_send_to_lower(p_cmd)) {
753 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
754 return NFC_STATUS_OK;
755 } else {
756 return NFC_STATUS_FAILED;
757 }
758 }
759
760 /*******************************************************************************
761 **
762 ** Function rw_i93_send_cmd_lock_block
763 **
764 ** Description Send Lock Block Request to VICC
765 **
766 ** STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
767 ** do not support.
768 **
769 ** Returns tNFC_STATUS
770 **
771 *******************************************************************************/
rw_i93_send_cmd_lock_block(uint8_t block_number)772 tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
773 NFC_HDR* p_cmd;
774 uint8_t* p;
775
776 RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_block ()");
777
778 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
779
780 if (!p_cmd) {
781 RW_TRACE_ERROR0("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
782 return NFC_STATUS_NO_BUFFERS;
783 }
784
785 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
786 p_cmd->len = 11;
787 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
788
789 /* Flags */
790 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
791 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
792 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
793 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
794 /* Option must be set for TI tag */
795 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
796 RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
797 } else {
798 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
799 RW_I93_FLAG_DATA_RATE));
800 }
801
802 /* Command Code */
803 UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
804
805 /* Parameters */
806 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
807 UINT8_TO_STREAM(p, block_number); /* Block number */
808
809 if (rw_i93_send_to_lower(p_cmd)) {
810 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
811 return NFC_STATUS_OK;
812 } else {
813 return NFC_STATUS_FAILED;
814 }
815 }
816
817 /*******************************************************************************
818 **
819 ** Function rw_i93_send_cmd_read_multi_blocks
820 **
821 ** Description Send Read Multiple Blocks Request to VICC
822 **
823 ** Returns tNFC_STATUS
824 **
825 *******************************************************************************/
rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,uint16_t number_blocks)826 tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
827 uint16_t number_blocks) {
828 NFC_HDR* p_cmd;
829 uint8_t *p, flags;
830
831 RW_TRACE_DEBUG0("rw_i93_send_cmd_read_multi_blocks ()");
832
833 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
834
835 if (!p_cmd) {
836 RW_TRACE_ERROR0(
837 "rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
838 return NFC_STATUS_NO_BUFFERS;
839 }
840
841 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
842 p_cmd->len = 12;
843 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
844
845 /* Flags */
846 flags =
847 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
848
849 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
850 flags |= I93_FLAG_PROT_EXT_YES;
851
852 UINT8_TO_STREAM(p, flags);
853
854 /* Command Code */
855 UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
856
857 /* Parameters */
858 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
859
860 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
861 UINT16_TO_STREAM(p, first_block_number); /* First block number */
862 p_cmd->len++;
863 } else {
864 UINT8_TO_STREAM(p, first_block_number); /* First block number */
865 }
866
867 UINT8_TO_STREAM(
868 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
869
870 if (rw_i93_send_to_lower(p_cmd)) {
871 rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
872 return NFC_STATUS_OK;
873 } else {
874 return NFC_STATUS_FAILED;
875 }
876 }
877
878 /*******************************************************************************
879 **
880 ** Function rw_i93_send_cmd_write_multi_blocks
881 **
882 ** Description Send Write Multiple Blocks Request to VICC
883 **
884 ** Returns tNFC_STATUS
885 **
886 *******************************************************************************/
rw_i93_send_cmd_write_multi_blocks(uint8_t first_block_number,uint16_t number_blocks,uint8_t * p_data)887 tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint8_t first_block_number,
888 uint16_t number_blocks,
889 uint8_t* p_data) {
890 NFC_HDR* p_cmd;
891 uint8_t* p;
892
893 RW_TRACE_DEBUG0("rw_i93_send_cmd_write_multi_blocks ()");
894
895 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
896
897 if (!p_cmd) {
898 RW_TRACE_ERROR0(
899 "rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
900 return NFC_STATUS_NO_BUFFERS;
901 }
902
903 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
904 p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
905 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
906
907 /* Flags */
908 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
909 RW_I93_FLAG_DATA_RATE));
910
911 /* Command Code */
912 UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
913
914 /* Parameters */
915 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
916 UINT8_TO_STREAM(p, first_block_number); /* First block number */
917 UINT8_TO_STREAM(
918 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
919
920 /* Data */
921 ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
922
923 if (rw_i93_send_to_lower(p_cmd)) {
924 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
925 return NFC_STATUS_OK;
926 } else {
927 return NFC_STATUS_FAILED;
928 }
929 }
930
931 /*******************************************************************************
932 **
933 ** Function rw_i93_send_cmd_select
934 **
935 ** Description Send Select Request to VICC
936 **
937 ** Returns tNFC_STATUS
938 **
939 *******************************************************************************/
rw_i93_send_cmd_select(uint8_t * p_uid)940 tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
941 NFC_HDR* p_cmd;
942 uint8_t* p;
943
944 RW_TRACE_DEBUG0("rw_i93_send_cmd_select ()");
945
946 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
947
948 if (!p_cmd) {
949 RW_TRACE_ERROR0("rw_i93_send_cmd_select (): Cannot allocate buffer");
950 return NFC_STATUS_NO_BUFFERS;
951 }
952
953 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
954 p_cmd->len = 10;
955 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
956
957 /* Flags */
958 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
959 RW_I93_FLAG_DATA_RATE));
960
961 /* Command Code */
962 UINT8_TO_STREAM(p, I93_CMD_SELECT);
963
964 /* Parameters */
965 ARRAY8_TO_STREAM(p, p_uid); /* UID */
966
967 if (rw_i93_send_to_lower(p_cmd)) {
968 rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
969 return NFC_STATUS_OK;
970 } else {
971 return NFC_STATUS_FAILED;
972 }
973 }
974
975 /*******************************************************************************
976 **
977 ** Function rw_i93_send_cmd_reset_to_ready
978 **
979 ** Description Send Reset to Ready Request to VICC
980 **
981 ** Returns tNFC_STATUS
982 **
983 *******************************************************************************/
rw_i93_send_cmd_reset_to_ready(void)984 tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
985 NFC_HDR* p_cmd;
986 uint8_t* p;
987
988 RW_TRACE_DEBUG0("rw_i93_send_cmd_reset_to_ready ()");
989
990 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
991
992 if (!p_cmd) {
993 RW_TRACE_ERROR0(
994 "rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
995 return NFC_STATUS_NO_BUFFERS;
996 }
997
998 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
999 p_cmd->len = 10;
1000 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1001
1002 /* Flags */
1003 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1004 RW_I93_FLAG_DATA_RATE));
1005
1006 /* Command Code */
1007 UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
1008
1009 /* Parameters */
1010 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1011
1012 if (rw_i93_send_to_lower(p_cmd)) {
1013 rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
1014 return NFC_STATUS_OK;
1015 } else {
1016 return NFC_STATUS_FAILED;
1017 }
1018 }
1019
1020 /*******************************************************************************
1021 **
1022 ** Function rw_i93_send_cmd_write_afi
1023 **
1024 ** Description Send Write AFI Request to VICC
1025 **
1026 ** Returns tNFC_STATUS
1027 **
1028 *******************************************************************************/
rw_i93_send_cmd_write_afi(uint8_t afi)1029 tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
1030 NFC_HDR* p_cmd;
1031 uint8_t* p;
1032
1033 RW_TRACE_DEBUG0("rw_i93_send_cmd_write_afi ()");
1034
1035 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1036
1037 if (!p_cmd) {
1038 RW_TRACE_ERROR0("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
1039 return NFC_STATUS_NO_BUFFERS;
1040 }
1041
1042 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1043 p_cmd->len = 11;
1044 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1045
1046 /* Flags */
1047 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1048 RW_I93_FLAG_DATA_RATE));
1049
1050 /* Command Code */
1051 UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
1052
1053 /* Parameters */
1054 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1055 UINT8_TO_STREAM(p, afi); /* AFI */
1056
1057 if (rw_i93_send_to_lower(p_cmd)) {
1058 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
1059 return NFC_STATUS_OK;
1060 } else {
1061 return NFC_STATUS_FAILED;
1062 }
1063 }
1064
1065 /*******************************************************************************
1066 **
1067 ** Function rw_i93_send_cmd_lock_afi
1068 **
1069 ** Description Send Lock AFI Request to VICC
1070 **
1071 ** Returns tNFC_STATUS
1072 **
1073 *******************************************************************************/
rw_i93_send_cmd_lock_afi(void)1074 tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
1075 NFC_HDR* p_cmd;
1076 uint8_t* p;
1077
1078 RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_afi ()");
1079
1080 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1081
1082 if (!p_cmd) {
1083 RW_TRACE_ERROR0("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
1084 return NFC_STATUS_NO_BUFFERS;
1085 }
1086
1087 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1088 p_cmd->len = 10;
1089 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1090
1091 /* Flags */
1092 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1093 RW_I93_FLAG_DATA_RATE));
1094
1095 /* Command Code */
1096 UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
1097
1098 /* Parameters */
1099 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1100
1101 if (rw_i93_send_to_lower(p_cmd)) {
1102 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
1103 return NFC_STATUS_OK;
1104 } else {
1105 return NFC_STATUS_FAILED;
1106 }
1107 }
1108
1109 /*******************************************************************************
1110 **
1111 ** Function rw_i93_send_cmd_write_dsfid
1112 **
1113 ** Description Send Write DSFID Request to VICC
1114 **
1115 ** Returns tNFC_STATUS
1116 **
1117 *******************************************************************************/
rw_i93_send_cmd_write_dsfid(uint8_t dsfid)1118 tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
1119 NFC_HDR* p_cmd;
1120 uint8_t* p;
1121
1122 RW_TRACE_DEBUG0("rw_i93_send_cmd_write_dsfid ()");
1123
1124 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1125
1126 if (!p_cmd) {
1127 RW_TRACE_ERROR0("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
1128 return NFC_STATUS_NO_BUFFERS;
1129 }
1130
1131 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1132 p_cmd->len = 11;
1133 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1134
1135 /* Flags */
1136 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1137 RW_I93_FLAG_DATA_RATE));
1138
1139 /* Command Code */
1140 UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
1141
1142 /* Parameters */
1143 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1144 UINT8_TO_STREAM(p, dsfid); /* DSFID */
1145
1146 if (rw_i93_send_to_lower(p_cmd)) {
1147 rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
1148 return NFC_STATUS_OK;
1149 } else {
1150 return NFC_STATUS_FAILED;
1151 }
1152 }
1153
1154 /*******************************************************************************
1155 **
1156 ** Function rw_i93_send_cmd_lock_dsfid
1157 **
1158 ** Description Send Lock DSFID Request to VICC
1159 **
1160 ** Returns tNFC_STATUS
1161 **
1162 *******************************************************************************/
rw_i93_send_cmd_lock_dsfid(void)1163 tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
1164 NFC_HDR* p_cmd;
1165 uint8_t* p;
1166
1167 RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_dsfid ()");
1168
1169 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1170
1171 if (!p_cmd) {
1172 RW_TRACE_ERROR0("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
1173 return NFC_STATUS_NO_BUFFERS;
1174 }
1175
1176 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1177 p_cmd->len = 10;
1178 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1179
1180 /* Flags */
1181 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1182 RW_I93_FLAG_DATA_RATE));
1183
1184 /* Command Code */
1185 UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
1186
1187 /* Parameters */
1188 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1189
1190 if (rw_i93_send_to_lower(p_cmd)) {
1191 rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
1192 return NFC_STATUS_OK;
1193 } else {
1194 return NFC_STATUS_FAILED;
1195 }
1196 }
1197
1198 /*******************************************************************************
1199 **
1200 ** Function rw_i93_send_cmd_get_sys_info
1201 **
1202 ** Description Send Get System Information Request to VICC
1203 **
1204 ** Returns tNFC_STATUS
1205 **
1206 *******************************************************************************/
rw_i93_send_cmd_get_sys_info(uint8_t * p_uid,uint8_t extra_flags)1207 tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
1208 NFC_HDR* p_cmd;
1209 uint8_t* p;
1210
1211 RW_TRACE_DEBUG0("rw_i93_send_cmd_get_sys_info ()");
1212
1213 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1214
1215 if (!p_cmd) {
1216 RW_TRACE_ERROR0("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
1217 return NFC_STATUS_NO_BUFFERS;
1218 }
1219
1220 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1221 p_cmd->len = 10;
1222 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1223
1224 /* Flags */
1225 UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
1226 RW_I93_FLAG_DATA_RATE | extra_flags));
1227
1228 /* Command Code */
1229 UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
1230
1231 /* Parameters */
1232 if (p_uid) {
1233 ARRAY8_TO_STREAM(p, p_uid); /* UID */
1234 } else {
1235 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1236 }
1237
1238 if (rw_i93_send_to_lower(p_cmd)) {
1239 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
1240 return NFC_STATUS_OK;
1241 } else {
1242 return NFC_STATUS_FAILED;
1243 }
1244 }
1245
1246 /*******************************************************************************
1247 **
1248 ** Function rw_i93_send_cmd_get_multi_block_sec
1249 **
1250 ** Description Send Get Multiple Block Security Status Request to VICC
1251 **
1252 ** Returns tNFC_STATUS
1253 **
1254 *******************************************************************************/
rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,uint16_t number_blocks)1255 tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
1256 uint16_t number_blocks) {
1257 NFC_HDR* p_cmd;
1258 uint8_t *p, flags;
1259
1260 RW_TRACE_DEBUG0("rw_i93_send_cmd_get_multi_block_sec ()");
1261
1262 p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1263
1264 if (!p_cmd) {
1265 RW_TRACE_ERROR0(
1266 "rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
1267 return NFC_STATUS_NO_BUFFERS;
1268 }
1269
1270 p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1271 p_cmd->len = 12;
1272 p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
1273
1274 /* Flags */
1275 flags =
1276 (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
1277
1278 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
1279 flags |= I93_FLAG_PROT_EXT_YES;
1280
1281 UINT8_TO_STREAM(p, flags);
1282
1283 /* Command Code */
1284 UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
1285
1286 /* Parameters */
1287 ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
1288
1289 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
1290 UINT16_TO_STREAM(p, first_block_number); /* First block number */
1291 UINT16_TO_STREAM(
1292 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1293 p_cmd->len += 2;
1294 } else {
1295 UINT8_TO_STREAM(p, first_block_number); /* First block number */
1296 UINT8_TO_STREAM(
1297 p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
1298 }
1299
1300 if (rw_i93_send_to_lower(p_cmd)) {
1301 rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
1302 return NFC_STATUS_OK;
1303 } else {
1304 return NFC_STATUS_FAILED;
1305 }
1306 }
1307
1308 /*******************************************************************************
1309 **
1310 ** Function rw_i93_get_next_blocks
1311 **
1312 ** Description Read as many blocks as possible (up to
1313 ** RW_I93_READ_MULTI_BLOCK_SIZE)
1314 **
1315 ** Returns tNFC_STATUS
1316 **
1317 *******************************************************************************/
rw_i93_get_next_blocks(uint16_t offset)1318 tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
1319 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1320 uint16_t first_block;
1321 uint16_t num_block;
1322
1323 RW_TRACE_DEBUG0("rw_i93_get_next_blocks ()");
1324
1325 first_block = offset / p_i93->block_size;
1326
1327 /* more blocks, more efficent but more error rate */
1328
1329 if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
1330 num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
1331
1332 if (num_block + first_block > p_i93->num_block)
1333 num_block = p_i93->num_block - first_block;
1334
1335 if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
1336 /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
1337 ** - The max number of blocks is 32 and they are all located in the
1338 ** same sector.
1339 ** - The sector is 32 blocks of 4 bytes.
1340 */
1341 if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
1342 (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
1343 (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
1344 (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
1345 (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
1346 if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
1347 num_block = I93_STM_MAX_BLOCKS_PER_READ;
1348
1349 if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
1350 ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
1351 num_block = I93_STM_BLOCKS_PER_SECTOR -
1352 (first_block % I93_STM_BLOCKS_PER_SECTOR);
1353 }
1354 }
1355 }
1356
1357 return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
1358 } else {
1359 return rw_i93_send_cmd_read_single_block(first_block, false);
1360 }
1361 }
1362
1363 /*******************************************************************************
1364 **
1365 ** Function rw_i93_get_next_block_sec
1366 **
1367 ** Description Get as many security of blocks as possible from
1368 ** p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1369 **
1370 ** Returns tNFC_STATUS
1371 **
1372 *******************************************************************************/
rw_i93_get_next_block_sec(void)1373 tNFC_STATUS rw_i93_get_next_block_sec(void) {
1374 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1375 uint16_t num_blocks;
1376
1377 RW_TRACE_DEBUG0("rw_i93_get_next_block_sec ()");
1378
1379 if (p_i93->num_block <= p_i93->rw_offset) {
1380 RW_TRACE_ERROR2("rw_offset(0x%x) must be less than num_block(0x%x)",
1381 p_i93->rw_offset, p_i93->num_block);
1382 return NFC_STATUS_FAILED;
1383 }
1384
1385 num_blocks = p_i93->num_block - p_i93->rw_offset;
1386
1387 if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
1388 num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
1389
1390 return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
1391 }
1392
1393 /*******************************************************************************
1394 **
1395 ** Function rw_i93_sm_detect_ndef
1396 **
1397 ** Description Process NDEF detection procedure
1398 **
1399 ** 1. Get UID if not having yet
1400 ** 2. Get System Info if not having yet
1401 ** 3. Read first block for CC
1402 ** 4. Search NDEF Type and length
1403 ** 5. Get block status to get max NDEF size and read-only
1404 ** status
1405 **
1406 ** Returns void
1407 **
1408 *******************************************************************************/
rw_i93_sm_detect_ndef(NFC_HDR * p_resp)1409 void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
1410 uint8_t *p = (uint8_t *)(p_resp + 1) + p_resp->offset, *p_uid;
1411 uint8_t flags, u8 = 0, cc[4];
1412 uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
1413 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1414 tRW_DATA rw_data;
1415 tNFC_STATUS status = NFC_STATUS_FAILED;
1416
1417 #if (BT_TRACE_VERBOSE == TRUE)
1418 RW_TRACE_DEBUG2("rw_i93_sm_detect_ndef () sub_state:%s (0x%x)",
1419 rw_i93_get_sub_state_name(p_i93->sub_state),
1420 p_i93->sub_state);
1421 #else
1422 RW_TRACE_DEBUG1("rw_i93_sm_detect_ndef () sub_state:0x%x", p_i93->sub_state);
1423 #endif
1424
1425 if (length == 0) {
1426 android_errorWriteLog(0x534e4554, "121260197");
1427 rw_i93_handle_error(NFC_STATUS_FAILED);
1428 return;
1429 }
1430 STREAM_TO_UINT8(flags, p);
1431 length--;
1432
1433 if (flags & I93_FLAG_ERROR_DETECTED) {
1434 if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
1435 /* getting system info with protocol extension flag */
1436 /* This STM tag supports more than 2040 bytes */
1437 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
1438 } else {
1439 RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
1440 rw_i93_handle_error(NFC_STATUS_FAILED);
1441 }
1442 return;
1443 }
1444
1445 switch (p_i93->sub_state) {
1446 case RW_I93_SUBSTATE_WAIT_UID:
1447
1448 if (length < (I93_UID_BYTE_LEN + 1)) {
1449 android_errorWriteLog(0x534e4554, "121260197");
1450 rw_i93_handle_error(NFC_STATUS_FAILED);
1451 return;
1452 }
1453 STREAM_TO_UINT8(u8, p); /* DSFID */
1454 p_uid = p_i93->uid;
1455 STREAM_TO_ARRAY8(p_uid, p);
1456
1457 if (u8 != I93_DFS_UNSUPPORTED) {
1458 /* if Data Storage Format is unknown */
1459 RW_TRACE_DEBUG1("Got unknown DSFID (0x%02x)", u8);
1460 rw_i93_handle_error(NFC_STATUS_FAILED);
1461 } else {
1462 /* get system information to get memory size */
1463 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
1464 NFC_STATUS_OK) {
1465 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
1466 } else {
1467 rw_i93_handle_error(NFC_STATUS_FAILED);
1468 }
1469 }
1470 break;
1471
1472 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
1473
1474 p_i93->block_size = 0;
1475 p_i93->num_block = 0;
1476
1477 if (!rw_i93_process_sys_info(p, length)) {
1478 /* retrying with protocol extension flag */
1479 break;
1480 }
1481
1482 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
1483 RW_TRACE_DEBUG0("Unable to get tag memory size");
1484 rw_i93_handle_error(status);
1485 } else {
1486 /* read CC in the first block */
1487 if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
1488 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
1489 } else {
1490 rw_i93_handle_error(NFC_STATUS_FAILED);
1491 }
1492 }
1493 break;
1494
1495 case RW_I93_SUBSTATE_WAIT_CC:
1496
1497 if (length < RW_I93_CC_SIZE) {
1498 android_errorWriteLog(0x534e4554, "139188579");
1499 rw_i93_handle_error(NFC_STATUS_FAILED);
1500 return;
1501 }
1502
1503 /* assume block size is more than RW_I93_CC_SIZE 4 */
1504 STREAM_TO_ARRAY(cc, p, RW_I93_CC_SIZE);
1505
1506 status = NFC_STATUS_FAILED;
1507
1508 /*
1509 ** Capability Container (CC)
1510 **
1511 ** CC[0] : magic number (0xE1)
1512 ** CC[1] : Bit 7-6:Major version number
1513 ** : Bit 5-4:Minor version number
1514 ** : Bit 3-2:Read access condition (00b: read access granted
1515 ** without any security)
1516 ** : Bit 1-0:Write access condition (00b: write access granted
1517 ** without any security)
1518 ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
1519 ** 0xFF if more than 2040bytes]
1520 ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
1521 ** : Bit 1:Inventory page read is supported [NXP]
1522 ** : Bit 2:More than 2040 bytes are supported [STM]
1523 */
1524
1525 RW_TRACE_DEBUG4(
1526 "rw_i93_sm_detect_ndef (): cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0],
1527 cc[1], cc[2], cc[3]);
1528 RW_TRACE_DEBUG2(
1529 "rw_i93_sm_detect_ndef (): Total blocks:0x%04X, Block size:0x%02X",
1530 p_i93->num_block, p_i93->block_size);
1531
1532 if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER) &&
1533 ((cc[3] & I93_STM_CC_OVERFLOW_MASK) ||
1534 (cc[2] * 8) == (p_i93->num_block * p_i93->block_size))) {
1535 if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
1536 I93_ICODE_CC_READ_ACCESS_GRANTED) {
1537 if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
1538 I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
1539 /* read-only or password required to write */
1540 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1541 }
1542 if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
1543 /* tag supports read multi blocks command */
1544 p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
1545 }
1546 status = NFC_STATUS_OK;
1547 }
1548 }
1549
1550 if (status == NFC_STATUS_OK) {
1551 /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
1552 */
1553 if (cc[2] != 0)
1554 p_i93->rw_offset = 4;
1555 else
1556 p_i93->rw_offset = 8;
1557
1558 if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1559 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1560 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1561 } else {
1562 rw_i93_handle_error(NFC_STATUS_FAILED);
1563 }
1564 } else {
1565 rw_i93_handle_error(NFC_STATUS_FAILED);
1566 }
1567 break;
1568
1569 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
1570
1571 /* search TLV within read blocks */
1572 for (xx = 0; xx < length; xx++) {
1573 /* if looking for type */
1574 if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
1575 if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
1576 continue;
1577 } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
1578 (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
1579 /* store found type and get length field */
1580 p_i93->tlv_type = *(p + xx);
1581 p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
1582
1583 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
1584 } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
1585 /* no NDEF TLV found */
1586 p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
1587 break;
1588 } else {
1589 RW_TRACE_DEBUG1("Invalid type: 0x%02x", *(p + xx));
1590 rw_i93_handle_error(NFC_STATUS_FAILED);
1591 return;
1592 }
1593 } else if (p_i93->tlv_detect_state ==
1594 RW_I93_TLV_DETECT_STATE_LENGTH_1) {
1595 /* if 3 bytes length field */
1596 if (*(p + xx) == 0xFF) {
1597 /* need 2 more bytes for length field */
1598 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
1599 } else {
1600 p_i93->tlv_length = *(p + xx);
1601 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1602
1603 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1604 p_i93->ndef_tlv_last_offset =
1605 p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
1606 break;
1607 }
1608 }
1609 } else if (p_i93->tlv_detect_state ==
1610 RW_I93_TLV_DETECT_STATE_LENGTH_2) {
1611 /* the second byte of 3 bytes length field */
1612 p_i93->tlv_length = *(p + xx);
1613 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
1614 } else if (p_i93->tlv_detect_state ==
1615 RW_I93_TLV_DETECT_STATE_LENGTH_3) {
1616 /* the last byte of 3 bytes length field */
1617 p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
1618 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
1619
1620 if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
1621 p_i93->ndef_tlv_last_offset =
1622 p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
1623 break;
1624 }
1625 } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
1626 /* this is other than NDEF TLV */
1627 if (p_i93->tlv_length <= length - xx) {
1628 /* skip value field */
1629 xx += (uint8_t)p_i93->tlv_length;
1630 p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
1631 } else {
1632 /* read more data */
1633 p_i93->tlv_length -= (length - xx);
1634 break;
1635 }
1636 }
1637 }
1638
1639 /* found NDEF TLV and read length field */
1640 if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
1641 (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
1642 p_i93->ndef_length = p_i93->tlv_length;
1643
1644 /* get lock status to see if read-only */
1645 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1646 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1647 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1648 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1649 /* these doesn't support GetMultiBlockSecurityStatus */
1650
1651 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
1652 first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
1653
1654 /* read block to get lock status */
1655 rw_i93_send_cmd_read_single_block(first_block, true);
1656 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1657 } else {
1658 /* block offset for read-only check */
1659 p_i93->rw_offset = 0;
1660
1661 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
1662 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
1663 } else {
1664 rw_i93_handle_error(NFC_STATUS_FAILED);
1665 }
1666 }
1667 } else {
1668 /* read more data */
1669 p_i93->rw_offset += length;
1670
1671 if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
1672 rw_i93_handle_error(NFC_STATUS_FAILED);
1673 } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
1674 p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
1675 } else {
1676 rw_i93_handle_error(NFC_STATUS_FAILED);
1677 }
1678 }
1679 break;
1680
1681 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
1682
1683 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1684 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
1685 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
1686 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
1687 /* these doesn't support GetMultiBlockSecurityStatus */
1688
1689 block = (p_i93->rw_offset / p_i93->block_size);
1690 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1691
1692 if ((*p) & I93_BLOCK_LOCKED) {
1693 if (block <= last_block) {
1694 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1695 }
1696 } else {
1697 /* if we need to check more user blocks */
1698 if (block + 1 < p_i93->num_block) {
1699 p_i93->rw_offset += p_i93->block_size;
1700
1701 /* read block to get lock status */
1702 rw_i93_send_cmd_read_single_block(
1703 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
1704 break;
1705 }
1706 }
1707
1708 p_i93->max_ndef_length =
1709 p_i93->ndef_length
1710 /* add available bytes including the last block of NDEF TLV */
1711 + (p_i93->block_size * (block - last_block) + 1) -
1712 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1713 } else {
1714 if (p_i93->rw_offset == 0) {
1715 p_i93->max_ndef_length =
1716 p_i93->ndef_length
1717 /* add available bytes in the last block of NDEF TLV */
1718 + p_i93->block_size -
1719 (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
1720
1721 first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
1722 } else {
1723 first_block = 0;
1724 }
1725
1726 last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
1727 num_blocks = length;
1728
1729 for (block = first_block; block < num_blocks; block++) {
1730 /* if any block of NDEF TLV is locked */
1731 if ((block + p_i93->rw_offset) <= last_block) {
1732 if (*(p + block) & I93_BLOCK_LOCKED) {
1733 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
1734 break;
1735 }
1736 } else {
1737 if (*(p + block) & I93_BLOCK_LOCKED) {
1738 /* no more consecutive unlocked block */
1739 break;
1740 } else {
1741 /* add block size if not locked */
1742 p_i93->max_ndef_length += p_i93->block_size;
1743 }
1744 }
1745 }
1746
1747 /* update next security of block to check */
1748 p_i93->rw_offset += num_blocks;
1749
1750 /* if need to check more */
1751 if (p_i93->num_block > p_i93->rw_offset) {
1752 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
1753 rw_i93_handle_error(NFC_STATUS_FAILED);
1754 }
1755 break;
1756 }
1757 }
1758
1759 /* check if need to adjust max NDEF length */
1760 if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
1761 /* 3 bytes length field must be used */
1762 p_i93->max_ndef_length -= 2;
1763 }
1764
1765 rw_data.ndef.status = NFC_STATUS_OK;
1766 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
1767 rw_data.ndef.flags = 0;
1768 rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
1769 rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
1770 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
1771 rw_data.ndef.cur_size = p_i93->ndef_length;
1772
1773 if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
1774 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1775 rw_data.ndef.max_size = p_i93->ndef_length;
1776 } else {
1777 rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
1778 rw_data.ndef.max_size = p_i93->max_ndef_length;
1779 }
1780
1781 p_i93->state = RW_I93_STATE_IDLE;
1782 p_i93->sent_cmd = 0;
1783
1784 RW_TRACE_DEBUG3("NDEF cur_size(%d),max_size (%d), flags (0x%x)",
1785 rw_data.ndef.cur_size, rw_data.ndef.max_size,
1786 rw_data.ndef.flags);
1787
1788 (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
1789 break;
1790
1791 default:
1792 break;
1793 }
1794 }
1795
1796 /*******************************************************************************
1797 **
1798 ** Function rw_i93_sm_read_ndef
1799 **
1800 ** Description Process NDEF read procedure
1801 **
1802 ** Returns void
1803 **
1804 *******************************************************************************/
rw_i93_sm_read_ndef(NFC_HDR * p_resp)1805 void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
1806 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
1807 uint8_t flags;
1808 uint16_t offset, length = p_resp->len;
1809 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1810 tRW_DATA rw_data;
1811
1812 RW_TRACE_DEBUG0("rw_i93_sm_read_ndef ()");
1813
1814 if (length == 0) {
1815 android_errorWriteLog(0x534e4554, "122035770");
1816 rw_i93_handle_error(NFC_STATUS_FAILED);
1817 return;
1818 }
1819
1820 STREAM_TO_UINT8(flags, p);
1821 length--;
1822
1823 if (flags & I93_FLAG_ERROR_DETECTED) {
1824 RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
1825 rw_i93_handle_error(NFC_STATUS_FAILED);
1826 return;
1827 }
1828
1829 /* if this is the first block */
1830 if (p_i93->rw_length == 0) {
1831 /* get start of NDEF in the first block */
1832 offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
1833
1834 if (p_i93->ndef_length < 0xFF) {
1835 offset += 2;
1836 } else {
1837 offset += 4;
1838 }
1839
1840 /* adjust offset if read more blocks because the first block doesn't have
1841 * NDEF */
1842 offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
1843 } else {
1844 offset = 0;
1845 }
1846
1847 /* if read enough data to skip type and length field for the beginning */
1848 if (offset < length) {
1849 offset++; /* flags */
1850 p_resp->offset += offset;
1851 p_resp->len -= offset;
1852
1853 rw_data.data.status = NFC_STATUS_OK;
1854 rw_data.data.p_data = p_resp;
1855
1856 p_i93->rw_length += p_resp->len;
1857 } else {
1858 /* in case of no Ndef data included */
1859 p_resp->len = 0;
1860 }
1861
1862 /* if read all of NDEF data */
1863 if (p_i93->rw_length >= p_i93->ndef_length) {
1864 /* remove extra btyes in the last block */
1865 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
1866
1867 p_i93->state = RW_I93_STATE_IDLE;
1868 p_i93->sent_cmd = 0;
1869
1870 RW_TRACE_DEBUG2("NDEF read complete read (%d)/total (%d)", p_resp->len,
1871 p_i93->ndef_length);
1872
1873 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
1874 } else {
1875 RW_TRACE_DEBUG2("NDEF read segment read (%d)/total (%d)", p_resp->len,
1876 p_i93->ndef_length);
1877
1878 if (p_resp->len > 0) {
1879 (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
1880 }
1881
1882 /* this will make read data from next block */
1883 p_i93->rw_offset += length;
1884
1885 if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
1886 rw_i93_handle_error(NFC_STATUS_FAILED);
1887 }
1888 }
1889 }
1890
1891 /*******************************************************************************
1892 **
1893 ** Function rw_i93_sm_update_ndef
1894 **
1895 ** Description Process NDEF update procedure
1896 **
1897 ** 1. Set length field to zero
1898 ** 2. Write NDEF and Terminator TLV
1899 ** 3. Set length field to NDEF length
1900 **
1901 ** Returns void
1902 **
1903 *******************************************************************************/
rw_i93_sm_update_ndef(NFC_HDR * p_resp)1904 void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
1905 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
1906 uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
1907 uint16_t length = p_resp->len, block_number;
1908 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
1909 tRW_DATA rw_data;
1910
1911 #if (BT_TRACE_VERBOSE == TRUE)
1912 RW_TRACE_DEBUG2("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
1913 rw_i93_get_sub_state_name(p_i93->sub_state),
1914 p_i93->sub_state);
1915 #else
1916 RW_TRACE_DEBUG1("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
1917 #endif
1918
1919 if (length == 0 || p_i93->block_size > I93_MAX_BLOCK_LENGH) {
1920 android_errorWriteLog(0x534e4554, "122320256");
1921 rw_i93_handle_error(NFC_STATUS_FAILED);
1922 return;
1923 }
1924
1925 STREAM_TO_UINT8(flags, p);
1926 length--;
1927
1928 if (flags & I93_FLAG_ERROR_DETECTED) {
1929 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
1930 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
1931 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
1932 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
1933 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
1934 /* ignore error */
1935 } else {
1936 RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
1937 rw_i93_handle_error(NFC_STATUS_FAILED);
1938 return;
1939 }
1940 }
1941
1942 switch (p_i93->sub_state) {
1943 case RW_I93_SUBSTATE_RESET_LEN:
1944
1945 /* get offset of length field */
1946 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
1947
1948 if (length < length_offset) {
1949 android_errorWriteLog(0x534e4554, "122320256");
1950 rw_i93_handle_error(NFC_STATUS_FAILED);
1951 return;
1952 }
1953
1954 /* set length to zero */
1955 *(p + length_offset) = 0x00;
1956
1957 if (p_i93->ndef_length > 0) {
1958 /* if 3 bytes length field is needed */
1959 if (p_i93->ndef_length >= 0xFF) {
1960 xx = length_offset + 3;
1961 } else {
1962 xx = length_offset + 1;
1963 }
1964
1965 /* write the first part of NDEF in the same block */
1966 for (; xx < p_i93->block_size; xx++) {
1967 if (xx > length || p_i93->rw_length > p_i93->ndef_length) {
1968 android_errorWriteLog(0x534e4554, "122320256");
1969 rw_i93_handle_error(NFC_STATUS_FAILED);
1970 return;
1971 }
1972 if (p_i93->rw_length < p_i93->ndef_length) {
1973 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
1974 } else {
1975 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
1976 }
1977 }
1978 }
1979
1980 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
1981
1982 if (length < p_i93->block_size) {
1983 android_errorWriteLog(0x534e4554, "143109193");
1984 rw_i93_handle_error(NFC_STATUS_FAILED);
1985 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
1986 NFC_STATUS_OK) {
1987 /* update next writing offset */
1988 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
1989 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
1990 } else {
1991 rw_i93_handle_error(NFC_STATUS_FAILED);
1992 }
1993 break;
1994
1995 case RW_I93_SUBSTATE_WRITE_NDEF:
1996
1997 /* if it's not the end of tag memory */
1998 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
1999 block_number = p_i93->rw_offset / p_i93->block_size;
2000
2001 /* if we have more data to write */
2002 if (p_i93->rw_length < p_i93->ndef_length) {
2003 p = p_i93->p_update_data + p_i93->rw_length;
2004
2005 p_i93->rw_offset += p_i93->block_size;
2006 p_i93->rw_length += p_i93->block_size;
2007
2008 /* if this is the last block of NDEF TLV */
2009 if (p_i93->rw_length > p_i93->ndef_length) {
2010 /* length of NDEF TLV in the block */
2011 xx = (uint8_t)(p_i93->block_size -
2012 (p_i93->rw_length - p_i93->ndef_length));
2013
2014 /* set NULL TLV in the unused part of block */
2015 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2016 memcpy(buff, p, xx);
2017 p = buff;
2018
2019 /* if it's the end of tag memory */
2020 if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
2021 (xx < p_i93->block_size)) {
2022 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
2023 }
2024
2025 p_i93->ndef_tlv_last_offset =
2026 p_i93->rw_offset - p_i93->block_size + xx - 1;
2027 }
2028
2029 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2030 NFC_STATUS_OK) {
2031 rw_i93_handle_error(NFC_STATUS_FAILED);
2032 }
2033 } else {
2034 /* if this is the very next block of NDEF TLV */
2035 if (block_number ==
2036 (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
2037 p_i93->rw_offset += p_i93->block_size;
2038
2039 /* write Terminator TLV and NULL TLV */
2040 memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2041 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2042 p = buff;
2043
2044 if (rw_i93_send_cmd_write_single_block(block_number, p) !=
2045 NFC_STATUS_OK) {
2046 rw_i93_handle_error(NFC_STATUS_FAILED);
2047 }
2048 } else {
2049 /* finished writing NDEF and Terminator TLV */
2050 /* read length field to update length */
2051 block_number =
2052 (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2053
2054 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2055 NFC_STATUS_OK) {
2056 /* set offset to length field */
2057 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2058
2059 /* get size of length field */
2060 if (p_i93->ndef_length >= 0xFF) {
2061 p_i93->rw_length = 3;
2062 } else if (p_i93->ndef_length > 0) {
2063 p_i93->rw_length = 1;
2064 } else {
2065 p_i93->rw_length = 0;
2066 }
2067
2068 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2069 } else {
2070 rw_i93_handle_error(NFC_STATUS_FAILED);
2071 }
2072 }
2073 }
2074 } else {
2075 /* if we have no more data to write */
2076 if (p_i93->rw_length >= p_i93->ndef_length) {
2077 /* finished writing NDEF and Terminator TLV */
2078 /* read length field to update length */
2079 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2080
2081 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
2082 NFC_STATUS_OK) {
2083 /* set offset to length field */
2084 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2085
2086 /* get size of length field */
2087 if (p_i93->ndef_length >= 0xFF) {
2088 p_i93->rw_length = 3;
2089 } else if (p_i93->ndef_length > 0) {
2090 p_i93->rw_length = 1;
2091 } else {
2092 p_i93->rw_length = 0;
2093 }
2094
2095 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2096 break;
2097 }
2098 }
2099 rw_i93_handle_error(NFC_STATUS_FAILED);
2100 }
2101 break;
2102
2103 case RW_I93_SUBSTATE_UPDATE_LEN:
2104
2105 /* if we have more length field to write */
2106 if (p_i93->rw_length > 0) {
2107 /* if we got ack for writing, read next block to update rest of length
2108 * field */
2109 if (length == 0) {
2110 block_number = p_i93->rw_offset / p_i93->block_size;
2111
2112 if (rw_i93_send_cmd_read_single_block(block_number, false) !=
2113 NFC_STATUS_OK) {
2114 rw_i93_handle_error(NFC_STATUS_FAILED);
2115 }
2116 } else {
2117 length_offset = p_i93->rw_offset % p_i93->block_size;
2118
2119 /* update length field within the read block */
2120 for (xx = length_offset; xx < p_i93->block_size; xx++) {
2121 if (xx > length) {
2122 android_errorWriteLog(0x534e4554, "122320256");
2123 rw_i93_handle_error(NFC_STATUS_FAILED);
2124 return;
2125 }
2126
2127 if (p_i93->rw_length == 3)
2128 *(p + xx) = 0xFF;
2129 else if (p_i93->rw_length == 2)
2130 *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
2131 else if (p_i93->rw_length == 1)
2132 *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
2133
2134 p_i93->rw_length--;
2135 if (p_i93->rw_length == 0) break;
2136 }
2137
2138 block_number = (p_i93->rw_offset / p_i93->block_size);
2139
2140 if (length < p_i93->block_size) {
2141 android_errorWriteLog(0x534e4554, "143155861");
2142 rw_i93_handle_error(NFC_STATUS_FAILED);
2143 } else if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2144 NFC_STATUS_OK) {
2145 /* set offset to the beginning of next block */
2146 p_i93->rw_offset +=
2147 p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2148 } else {
2149 rw_i93_handle_error(NFC_STATUS_FAILED);
2150 }
2151 }
2152 } else {
2153 RW_TRACE_DEBUG3("NDEF update complete, %d bytes, (%d-%d)",
2154 p_i93->ndef_length, p_i93->ndef_tlv_start_offset,
2155 p_i93->ndef_tlv_last_offset);
2156
2157 p_i93->state = RW_I93_STATE_IDLE;
2158 p_i93->sent_cmd = 0;
2159 p_i93->p_update_data = NULL;
2160
2161 rw_data.status = NFC_STATUS_OK;
2162 (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2163 }
2164 break;
2165
2166 default:
2167 break;
2168 }
2169 }
2170
2171 /*******************************************************************************
2172 **
2173 ** Function rw_i93_sm_format
2174 **
2175 ** Description Process format procedure
2176 **
2177 ** 1. Get UID
2178 ** 2. Get sys info for memory size (reset AFI/DSFID)
2179 ** 3. Get block status to get read-only status
2180 ** 4. Write CC and empty NDEF
2181 **
2182 ** Returns void
2183 **
2184 *******************************************************************************/
rw_i93_sm_format(NFC_HDR * p_resp)2185 void rw_i93_sm_format(NFC_HDR* p_resp) {
2186 uint8_t *p = (uint8_t *)(p_resp + 1) + p_resp->offset, *p_uid;
2187 uint8_t flags;
2188 uint16_t length = p_resp->len, xx, block_number;
2189 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2190 tRW_DATA rw_data;
2191 tNFC_STATUS status = NFC_STATUS_FAILED;
2192
2193 #if (BT_TRACE_VERBOSE == TRUE)
2194 RW_TRACE_DEBUG2("rw_i93_sm_format () sub_state:%s (0x%x)",
2195 rw_i93_get_sub_state_name(p_i93->sub_state),
2196 p_i93->sub_state);
2197 #else
2198 RW_TRACE_DEBUG1("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
2199 #endif
2200
2201 STREAM_TO_UINT8(flags, p);
2202 length--;
2203
2204 if (flags & I93_FLAG_ERROR_DETECTED) {
2205 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2206 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2207 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2208 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2209 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2210 /* ignore error */
2211 } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
2212 /* getting system info with protocol extension flag */
2213 /* This STM tag supports more than 2040 bytes */
2214 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2215 return;
2216 } else {
2217 RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
2218 rw_i93_handle_error(NFC_STATUS_FAILED);
2219 return;
2220 }
2221 }
2222
2223 switch (p_i93->sub_state) {
2224 case RW_I93_SUBSTATE_WAIT_UID:
2225
2226 p++; /* skip DSFID */
2227 p_uid = p_i93->uid;
2228 STREAM_TO_ARRAY8(p_uid, p); /* store UID */
2229
2230 /* get system information to get memory size */
2231 if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
2232 NFC_STATUS_OK) {
2233 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2234 } else {
2235 rw_i93_handle_error(NFC_STATUS_FAILED);
2236 }
2237 break;
2238
2239 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2240
2241 p_i93->block_size = 0;
2242 p_i93->num_block = 0;
2243
2244 if (!rw_i93_process_sys_info(p, length)) {
2245 /* retrying with protocol extension flag */
2246 break;
2247 }
2248
2249 if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
2250 /* DSFID, if any DSFID then reset */
2251 if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
2252 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2253 }
2254 }
2255 if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
2256 /* AFI, reset to 0 */
2257 if (p_i93->afi != 0x00) {
2258 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2259 }
2260 }
2261
2262 if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
2263 RW_TRACE_DEBUG0("Unable to get tag memory size");
2264 rw_i93_handle_error(status);
2265 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2266 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2267 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2268 } else {
2269 rw_i93_handle_error(NFC_STATUS_FAILED);
2270 }
2271 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2272 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2273 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2274 } else {
2275 rw_i93_handle_error(NFC_STATUS_FAILED);
2276 }
2277 } else {
2278 /* get lock status to see if read-only */
2279 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2280 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2281 /* these doesn't support GetMultiBlockSecurityStatus */
2282
2283 rw_cb.tcb.i93.rw_offset = 0;
2284
2285 /* read blocks with option flag to get block security status */
2286 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2287 NFC_STATUS_OK) {
2288 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2289 } else {
2290 rw_i93_handle_error(NFC_STATUS_FAILED);
2291 }
2292 } else {
2293 /* block offset for read-only check */
2294 p_i93->rw_offset = 0;
2295
2296 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2297 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2298 } else {
2299 rw_i93_handle_error(NFC_STATUS_FAILED);
2300 }
2301 }
2302 }
2303
2304 break;
2305
2306 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2307
2308 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
2309 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2310 } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
2311 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2312 }
2313
2314 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
2315 if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
2316 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2317 } else {
2318 rw_i93_handle_error(NFC_STATUS_FAILED);
2319 }
2320 } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
2321 if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
2322 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2323 } else {
2324 rw_i93_handle_error(NFC_STATUS_FAILED);
2325 }
2326 } else {
2327 /* get lock status to see if read-only */
2328 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2329 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
2330 /* these doesn't support GetMultiBlockSecurityStatus */
2331
2332 rw_cb.tcb.i93.rw_offset = 0;
2333
2334 /* read blocks with option flag to get block security status */
2335 if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
2336 NFC_STATUS_OK) {
2337 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2338 } else {
2339 rw_i93_handle_error(NFC_STATUS_FAILED);
2340 }
2341 } else {
2342 /* block offset for read-only check */
2343 p_i93->rw_offset = 0;
2344
2345 if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
2346 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2347 } else {
2348 rw_i93_handle_error(NFC_STATUS_FAILED);
2349 }
2350 }
2351 }
2352 break;
2353
2354 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2355
2356 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2357 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
2358 ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
2359 (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
2360 if ((*p) & I93_BLOCK_LOCKED) {
2361 rw_i93_handle_error(NFC_STATUS_FAILED);
2362 break;
2363 }
2364
2365 /* if we checked all of user blocks */
2366 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
2367 if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2368 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2369 /* read the block which has AFI */
2370 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2371 rw_i93_send_cmd_read_single_block(
2372 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2373 break;
2374 }
2375 } else if (p_i93->rw_offset ==
2376 I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
2377 /* no block is locked */
2378 } else {
2379 p_i93->rw_offset += p_i93->block_size;
2380 rw_i93_send_cmd_read_single_block(
2381 (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
2382 break;
2383 }
2384 } else {
2385 /* if any block is locked, we cannot format it */
2386 for (xx = 0; xx < length; xx++) {
2387 if (*(p + xx) & I93_BLOCK_LOCKED) {
2388 rw_i93_handle_error(NFC_STATUS_FAILED);
2389 break;
2390 }
2391 }
2392
2393 /* update block offset for read-only check */
2394 p_i93->rw_offset += length;
2395
2396 /* if need to get more lock status of blocks */
2397 if (p_i93->num_block > p_i93->rw_offset) {
2398 if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
2399 rw_i93_handle_error(NFC_STATUS_FAILED);
2400 }
2401 break;
2402 }
2403 }
2404
2405 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2406 /* Block size could be either 4 or 8 or 16 or 32 bytes */
2407 /* Get buffer for the largest block size I93_MAX_BLOCK_LENGH */
2408 p_i93->p_update_data = (uint8_t*)GKI_getbuf(I93_MAX_BLOCK_LENGH);
2409
2410 if (!p_i93->p_update_data) {
2411 RW_TRACE_ERROR0("rw_i93_sm_format (): Cannot allocate buffer");
2412 rw_i93_handle_error(NFC_STATUS_FAILED);
2413 break;
2414 } else if (p_i93->block_size > RW_I93_FORMAT_DATA_LEN) {
2415 /* Possible leaking information from previous NFC transactions */
2416 /* Clear previous values */
2417 memset(p_i93->p_update_data, I93_ICODE_TLV_TYPE_NULL,
2418 I93_MAX_BLOCK_LENGH);
2419 android_errorWriteLog(0x534e4554, "139738828");
2420 }
2421
2422 p = p_i93->p_update_data;
2423
2424 /* Capability Container */
2425 *(p++) = I93_ICODE_CC_MAGIC_NUMER; /* magic number */
2426 *(p++) = 0x40; /* version 1.0, read/write */
2427
2428 /* if memory size is less than 2048 bytes */
2429 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2430 *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
2431 8); /* memory size */
2432 else
2433 *(p++) = 0xFF;
2434
2435 if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
2436 (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
2437 (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
2438 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2439 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2440 else
2441 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2442 supported */
2443 } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2444 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
2445 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
2446 supported */
2447 } else if ((p_i93->product_version ==
2448 RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2449 (p_i93->product_version ==
2450 RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
2451 *(p++) = 0;
2452 } else {
2453 /* STM except LRIS2K, Broadcom supports read multi block command */
2454
2455 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2456 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2457 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2458 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2459 *(p++) = 0x00;
2460 else
2461 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2462 }
2463
2464 /* zero length NDEF and Terminator TLV */
2465 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2466 *(p++) = 0x00;
2467 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2468 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2469
2470 /* start from block 0 */
2471 p_i93->rw_offset = 0;
2472
2473 if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
2474 NFC_STATUS_OK) {
2475 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2476 p_i93->rw_offset += p_i93->block_size;
2477 } else {
2478 rw_i93_handle_error(NFC_STATUS_FAILED);
2479 }
2480 break;
2481
2482 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2483
2484 /* if we have more data to write */
2485 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
2486 block_number = (p_i93->rw_offset / p_i93->block_size);
2487 p = p_i93->p_update_data + p_i93->rw_offset;
2488
2489 if (rw_i93_send_cmd_write_single_block(block_number, p) ==
2490 NFC_STATUS_OK) {
2491 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2492 p_i93->rw_offset += p_i93->block_size;
2493 } else {
2494 rw_i93_handle_error(NFC_STATUS_FAILED);
2495 }
2496 } else {
2497 GKI_freebuf(p_i93->p_update_data);
2498 p_i93->p_update_data = NULL;
2499
2500 p_i93->state = RW_I93_STATE_IDLE;
2501 p_i93->sent_cmd = 0;
2502
2503 rw_data.status = NFC_STATUS_OK;
2504 (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
2505 }
2506 break;
2507
2508 default:
2509 break;
2510 }
2511 }
2512
2513 /*******************************************************************************
2514 **
2515 ** Function rw_i93_sm_set_read_only
2516 **
2517 ** Description Process read-only procedure
2518 **
2519 ** 1. Update CC as read-only
2520 ** 2. Lock all block of NDEF TLV
2521 ** 3. Lock block of CC
2522 **
2523 ** Returns void
2524 **
2525 *******************************************************************************/
rw_i93_sm_set_read_only(NFC_HDR * p_resp)2526 void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
2527 uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
2528 uint8_t flags, block_number;
2529 uint16_t length = p_resp->len;
2530 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2531 tRW_DATA rw_data;
2532
2533 #if (BT_TRACE_VERBOSE == TRUE)
2534 RW_TRACE_DEBUG2("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
2535 rw_i93_get_sub_state_name(p_i93->sub_state),
2536 p_i93->sub_state);
2537 #else
2538 RW_TRACE_DEBUG1("rw_i93_sm_set_read_only () sub_state:0x%x",
2539 p_i93->sub_state);
2540 #endif
2541
2542 STREAM_TO_UINT8(flags, p);
2543 length--;
2544
2545 if (flags & I93_FLAG_ERROR_DETECTED) {
2546 if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
2547 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
2548 (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2549 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
2550 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
2551 /* ignore error */
2552 } else {
2553 RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
2554 rw_i93_handle_error(NFC_STATUS_FAILED);
2555 return;
2556 }
2557 }
2558
2559 switch (p_i93->sub_state) {
2560 case RW_I93_SUBSTATE_WAIT_CC:
2561
2562 if (length < RW_I93_CC_SIZE) {
2563 android_errorWriteLog(0x534e4554, "139188579");
2564 rw_i93_handle_error(NFC_STATUS_FAILED);
2565 return;
2566 }
2567
2568 /* mark CC as read-only */
2569 *(p + 1) |= I93_ICODE_CC_READ_ONLY;
2570
2571 if (length < p_i93->block_size) {
2572 android_errorWriteLog(0x534e4554, "143106535");
2573 rw_i93_handle_error(NFC_STATUS_FAILED);
2574 } else if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
2575 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2576 } else {
2577 rw_i93_handle_error(NFC_STATUS_FAILED);
2578 }
2579 break;
2580
2581 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2582
2583 /* successfully write CC then lock all blocks of NDEF TLV */
2584 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2585 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
2586
2587 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2588 p_i93->rw_offset += p_i93->block_size;
2589 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2590 } else {
2591 rw_i93_handle_error(NFC_STATUS_FAILED);
2592 }
2593 break;
2594
2595 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2596
2597 /* if we need to lock more blocks */
2598 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
2599 /* get the next block of NDEF TLV */
2600 block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
2601
2602 if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
2603 p_i93->rw_offset += p_i93->block_size;
2604 } else {
2605 rw_i93_handle_error(NFC_STATUS_FAILED);
2606 }
2607 }
2608 /* if the first block of NDEF TLV is different from block of CC */
2609 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
2610 /* lock block of CC */
2611 if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
2612 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2613 } else {
2614 rw_i93_handle_error(NFC_STATUS_FAILED);
2615 }
2616 } else {
2617 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2618 p_i93->state = RW_I93_STATE_IDLE;
2619 p_i93->sent_cmd = 0;
2620
2621 rw_data.status = NFC_STATUS_OK;
2622 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2623 }
2624 break;
2625
2626 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2627
2628 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2629 p_i93->state = RW_I93_STATE_IDLE;
2630 p_i93->sent_cmd = 0;
2631
2632 rw_data.status = NFC_STATUS_OK;
2633 (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
2634 break;
2635
2636 default:
2637 break;
2638 }
2639 }
2640
2641 /*******************************************************************************
2642 **
2643 ** Function rw_i93_handle_error
2644 **
2645 ** Description notify error to application and clean up
2646 **
2647 ** Returns none
2648 **
2649 *******************************************************************************/
rw_i93_handle_error(tNFC_STATUS status)2650 void rw_i93_handle_error(tNFC_STATUS status) {
2651 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2652 tRW_DATA rw_data;
2653 tRW_EVENT event;
2654
2655 RW_TRACE_DEBUG2("rw_i93_handle_error (): status:0x%02X, state:0x%X", status,
2656 p_i93->state);
2657
2658 nfc_stop_quick_timer(&p_i93->timer);
2659
2660 if (rw_cb.p_cback) {
2661 rw_data.status = status;
2662
2663 switch (p_i93->state) {
2664 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2665 event = RW_I93_INTF_ERROR_EVT;
2666 break;
2667
2668 case RW_I93_STATE_BUSY:
2669 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
2670 /* There is no response to Stay Quiet command */
2671 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2672 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2673 rw_data.i93_cmd_cmpl.error_code = 0;
2674 event = RW_I93_CMD_CMPL_EVT;
2675 } else {
2676 event = RW_I93_INTF_ERROR_EVT;
2677 }
2678 break;
2679
2680 case RW_I93_STATE_DETECT_NDEF:
2681 rw_data.ndef.protocol = NFC_PROTOCOL_T5T;
2682 rw_data.ndef.cur_size = 0;
2683 rw_data.ndef.max_size = 0;
2684 rw_data.ndef.flags = 0;
2685 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2686 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2687 event = RW_I93_NDEF_DETECT_EVT;
2688 break;
2689
2690 case RW_I93_STATE_READ_NDEF:
2691 event = RW_I93_NDEF_READ_FAIL_EVT;
2692 break;
2693
2694 case RW_I93_STATE_UPDATE_NDEF:
2695 p_i93->p_update_data = NULL;
2696 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2697 break;
2698
2699 case RW_I93_STATE_FORMAT:
2700 if (p_i93->p_update_data) {
2701 GKI_freebuf(p_i93->p_update_data);
2702 p_i93->p_update_data = NULL;
2703 }
2704 event = RW_I93_FORMAT_CPLT_EVT;
2705 break;
2706
2707 case RW_I93_STATE_SET_READ_ONLY:
2708 event = RW_I93_SET_TAG_RO_EVT;
2709 break;
2710
2711 case RW_I93_STATE_PRESENCE_CHECK:
2712 event = RW_I93_PRESENCE_CHECK_EVT;
2713 break;
2714
2715 default:
2716 event = RW_I93_MAX_EVT;
2717 break;
2718 }
2719
2720 p_i93->state = RW_I93_STATE_IDLE;
2721 p_i93->sent_cmd = 0;
2722
2723 if (event != RW_I93_MAX_EVT) {
2724 (*(rw_cb.p_cback))(event, &rw_data);
2725 }
2726 } else {
2727 p_i93->state = RW_I93_STATE_IDLE;
2728 }
2729 }
2730
2731 /*******************************************************************************
2732 **
2733 ** Function rw_i93_process_timeout
2734 **
2735 ** Description process timeout event
2736 **
2737 ** Returns none
2738 **
2739 *******************************************************************************/
rw_i93_process_timeout(TIMER_LIST_ENT * p_tle)2740 void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
2741 NFC_HDR* p_buf;
2742
2743 RW_TRACE_DEBUG1("rw_i93_process_timeout () event=%d", p_tle->event);
2744
2745 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
2746 if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
2747 (rw_cb.tcb.i93.p_retry_cmd) &&
2748 (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
2749 rw_cb.tcb.i93.retry_count++;
2750 RW_TRACE_ERROR1("rw_i93_process_timeout (): retry_count = %d",
2751 rw_cb.tcb.i93.retry_count);
2752
2753 p_buf = rw_cb.tcb.i93.p_retry_cmd;
2754 rw_cb.tcb.i93.p_retry_cmd = NULL;
2755
2756 if (rw_i93_send_to_lower(p_buf)) {
2757 return;
2758 }
2759 }
2760
2761 /* all retrial is done or failed to send command to lower layer */
2762 if (rw_cb.tcb.i93.p_retry_cmd) {
2763 GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
2764 rw_cb.tcb.i93.p_retry_cmd = NULL;
2765 rw_cb.tcb.i93.retry_count = 0;
2766 }
2767 rw_i93_handle_error(NFC_STATUS_TIMEOUT);
2768 } else {
2769 RW_TRACE_ERROR1("rw_i93_process_timeout () unknown event=%d", p_tle->event);
2770 }
2771 }
2772
2773 /*******************************************************************************
2774 **
2775 ** Function rw_i93_data_cback
2776 **
2777 ** Description This callback function receives the data from NFCC.
2778 **
2779 ** Returns none
2780 **
2781 *******************************************************************************/
rw_i93_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2782 static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
2783 tNFC_CONN* p_data) {
2784 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2785 NFC_HDR* p_resp;
2786 tRW_DATA rw_data;
2787
2788 #if (BT_TRACE_VERBOSE == TRUE)
2789 uint8_t begin_state = p_i93->state;
2790 #endif
2791
2792 RW_TRACE_DEBUG1("rw_i93_data_cback () event = 0x%X", event);
2793
2794 if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT) ||
2795 ((event == NFC_DATA_CEVT) && (p_data->status != NFC_STATUS_OK))) {
2796 nfc_stop_quick_timer(&p_i93->timer);
2797
2798 if (event == NFC_ERROR_CEVT || (p_data->status != NFC_STATUS_OK)) {
2799 if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
2800 p_i93->retry_count++;
2801
2802 RW_TRACE_ERROR1("rw_i93_data_cback (): retry_count = %d",
2803 p_i93->retry_count);
2804
2805 p_resp = p_i93->p_retry_cmd;
2806 p_i93->p_retry_cmd = NULL;
2807 if (rw_i93_send_to_lower(p_resp)) {
2808 return;
2809 }
2810 }
2811
2812 /* all retrial is done or failed to send command to lower layer */
2813 if (p_i93->p_retry_cmd) {
2814 GKI_freebuf(p_i93->p_retry_cmd);
2815 p_i93->p_retry_cmd = NULL;
2816 p_i93->retry_count = 0;
2817 }
2818
2819 rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
2820 } else {
2821 /* free retry buffer */
2822 if (p_i93->p_retry_cmd) {
2823 GKI_freebuf(p_i93->p_retry_cmd);
2824 p_i93->p_retry_cmd = NULL;
2825 p_i93->retry_count = 0;
2826 }
2827 NFC_SetStaticRfCback(NULL);
2828 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
2829 }
2830 return;
2831 }
2832
2833 if (event != NFC_DATA_CEVT) {
2834 return;
2835 }
2836
2837 p_resp = (NFC_HDR*)p_data->data.p_data;
2838
2839 nfc_stop_quick_timer(&p_i93->timer);
2840
2841 /* free retry buffer */
2842 if (p_i93->p_retry_cmd) {
2843 GKI_freebuf(p_i93->p_retry_cmd);
2844 p_i93->p_retry_cmd = NULL;
2845 p_i93->retry_count = 0;
2846 }
2847
2848 #if (BT_TRACE_PROTOCOL == TRUE)
2849 DispRWI93Tag(p_resp, true, p_i93->sent_cmd);
2850 #endif
2851
2852 #if (BT_TRACE_VERBOSE == TRUE)
2853 RW_TRACE_DEBUG2("RW I93 state: <%s (%d)>",
2854 rw_i93_get_state_name(p_i93->state), p_i93->state);
2855 #else
2856 RW_TRACE_DEBUG1("RW I93 state: %d", p_i93->state);
2857 #endif
2858
2859 switch (p_i93->state) {
2860 case RW_I93_STATE_IDLE:
2861 /* Unexpected Response from VICC, it should be raw frame response */
2862 /* forward to upper layer without parsing */
2863 p_i93->sent_cmd = 0;
2864 if (rw_cb.p_cback) {
2865 rw_data.raw_frame.status = p_data->data.status;
2866 rw_data.raw_frame.p_data = p_resp;
2867 (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
2868 p_resp = NULL;
2869 } else {
2870 GKI_freebuf(p_resp);
2871 }
2872 break;
2873 case RW_I93_STATE_BUSY:
2874 p_i93->state = RW_I93_STATE_IDLE;
2875 rw_i93_send_to_upper(p_resp);
2876 GKI_freebuf(p_resp);
2877 break;
2878
2879 case RW_I93_STATE_DETECT_NDEF:
2880 rw_i93_sm_detect_ndef(p_resp);
2881 GKI_freebuf(p_resp);
2882 break;
2883
2884 case RW_I93_STATE_READ_NDEF:
2885 rw_i93_sm_read_ndef(p_resp);
2886 /* p_resp may send upper lyaer */
2887 break;
2888
2889 case RW_I93_STATE_UPDATE_NDEF:
2890 rw_i93_sm_update_ndef(p_resp);
2891 GKI_freebuf(p_resp);
2892 break;
2893
2894 case RW_I93_STATE_FORMAT:
2895 rw_i93_sm_format(p_resp);
2896 GKI_freebuf(p_resp);
2897 break;
2898
2899 case RW_I93_STATE_SET_READ_ONLY:
2900 rw_i93_sm_set_read_only(p_resp);
2901 GKI_freebuf(p_resp);
2902 break;
2903
2904 case RW_I93_STATE_PRESENCE_CHECK:
2905 p_i93->state = RW_I93_STATE_IDLE;
2906 p_i93->sent_cmd = 0;
2907
2908 /* if any response, send presence check with ok */
2909 rw_data.status = NFC_STATUS_OK;
2910 (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
2911 GKI_freebuf(p_resp);
2912 break;
2913
2914 default:
2915 RW_TRACE_ERROR1("rw_i93_data_cback (): invalid state=%d", p_i93->state);
2916 GKI_freebuf(p_resp);
2917 break;
2918 }
2919
2920 #if (BT_TRACE_VERBOSE == TRUE)
2921 if (begin_state != p_i93->state) {
2922 RW_TRACE_DEBUG2("RW I93 state changed:<%s> -> <%s>",
2923 rw_i93_get_state_name(begin_state),
2924 rw_i93_get_state_name(p_i93->state));
2925 }
2926 #endif
2927 }
2928
2929 /*******************************************************************************
2930 **
2931 ** Function rw_i93_select
2932 **
2933 ** Description Initialise ISO 15693 / T5T RW
2934 **
2935 ** Returns NFC_STATUS_OK if success
2936 **
2937 *******************************************************************************/
rw_i93_select(uint8_t * p_uid)2938 tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
2939 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
2940 uint8_t uid[I93_UID_BYTE_LEN], *p;
2941
2942 RW_TRACE_DEBUG0("rw_i93_select ()");
2943
2944 NFC_SetStaticRfCback(rw_i93_data_cback);
2945
2946 p_i93->state = RW_I93_STATE_IDLE;
2947
2948 /* convert UID to big endian format - MSB(0xE0) in first byte */
2949 p = uid;
2950 STREAM_TO_ARRAY8(p, p_uid);
2951
2952 rw_i93_get_product_version(uid);
2953
2954 return NFC_STATUS_OK;
2955 }
2956
2957 /*******************************************************************************
2958 **
2959 ** Function RW_I93Inventory
2960 **
2961 ** Description This function send Inventory command with/without AFI
2962 ** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
2963 **
2964 ** RW_I93_RESPONSE_EVT will be returned
2965 **
2966 ** Returns NFC_STATUS_OK if success
2967 ** NFC_STATUS_NO_BUFFERS if out of buffer
2968 ** NFC_STATUS_BUSY if busy
2969 ** NFC_STATUS_FAILED if other error
2970 **
2971 *******************************************************************************/
RW_I93Inventory(bool including_afi,uint8_t afi,uint8_t * p_uid)2972 tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
2973 tNFC_STATUS status;
2974
2975 RW_TRACE_API2("RW_I93Inventory (), including_afi:%d, AFI:0x%02X",
2976 including_afi, afi);
2977
2978 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
2979 RW_TRACE_ERROR1(
2980 "RW_I93Inventory ():Unable to start command at state (0x%X)",
2981 rw_cb.tcb.i93.state);
2982 return NFC_STATUS_BUSY;
2983 }
2984
2985 status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
2986
2987 if (status == NFC_STATUS_OK) {
2988 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
2989 }
2990
2991 return (status);
2992 }
2993
2994 /*******************************************************************************
2995 **
2996 ** Function RW_I93StayQuiet
2997 **
2998 ** Description This function send Inventory command
2999 **
3000 ** RW_I93_CMD_CMPL_EVT will be returned
3001 **
3002 ** Returns NFC_STATUS_OK if success
3003 ** NFC_STATUS_NO_BUFFERS if out of buffer
3004 ** NFC_STATUS_BUSY if busy
3005 ** NFC_STATUS_FAILED if other error
3006 **
3007 *******************************************************************************/
RW_I93StayQuiet(void)3008 tNFC_STATUS RW_I93StayQuiet(void) {
3009 tNFC_STATUS status;
3010
3011 RW_TRACE_API0("RW_I93StayQuiet ()");
3012
3013 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3014 RW_TRACE_ERROR1(
3015 "RW_I93StayQuiet ():Unable to start command at state (0x%X)",
3016 rw_cb.tcb.i93.state);
3017 return NFC_STATUS_BUSY;
3018 }
3019
3020 status = rw_i93_send_cmd_stay_quiet();
3021 if (status == NFC_STATUS_OK) {
3022 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3023 }
3024
3025 return status;
3026 }
3027
3028 /*******************************************************************************
3029 **
3030 ** Function RW_I93ReadSingleBlock
3031 **
3032 ** Description This function send Read Single Block command
3033 **
3034 ** RW_I93_RESPONSE_EVT will be returned
3035 **
3036 ** Returns NFC_STATUS_OK if success
3037 ** NFC_STATUS_NO_BUFFERS if out of buffer
3038 ** NFC_STATUS_BUSY if busy
3039 ** NFC_STATUS_FAILED if other error
3040 **
3041 *******************************************************************************/
RW_I93ReadSingleBlock(uint16_t block_number)3042 tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
3043 tNFC_STATUS status;
3044
3045 RW_TRACE_API1("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
3046
3047 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3048 RW_TRACE_ERROR1(
3049 "RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
3050 rw_cb.tcb.i93.state);
3051 return NFC_STATUS_BUSY;
3052 }
3053
3054 status = rw_i93_send_cmd_read_single_block(block_number, false);
3055 if (status == NFC_STATUS_OK) {
3056 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3057 }
3058
3059 return status;
3060 }
3061
3062 /*******************************************************************************
3063 **
3064 ** Function RW_I93WriteSingleBlock
3065 **
3066 ** Description This function send Write Single Block command
3067 ** Application must get block size first by calling
3068 ** RW_I93GetSysInfo().
3069 **
3070 ** RW_I93_CMD_CMPL_EVT will be returned
3071 **
3072 ** Returns NFC_STATUS_OK if success
3073 ** NFC_STATUS_NO_BUFFERS if out of buffer
3074 ** NFC_STATUS_BUSY if busy
3075 ** NFC_STATUS_FAILED if other error
3076 **
3077 *******************************************************************************/
RW_I93WriteSingleBlock(uint16_t block_number,uint8_t * p_data)3078 tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
3079 tNFC_STATUS status;
3080
3081 RW_TRACE_API0("RW_I93WriteSingleBlock ()");
3082
3083 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3084 RW_TRACE_ERROR1(
3085 "RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
3086 rw_cb.tcb.i93.state);
3087 return NFC_STATUS_BUSY;
3088 }
3089
3090 if (rw_cb.tcb.i93.block_size == 0) {
3091 RW_TRACE_ERROR0("RW_I93WriteSingleBlock ():Block size is unknown");
3092 return NFC_STATUS_FAILED;
3093 }
3094
3095 status = rw_i93_send_cmd_write_single_block(block_number, p_data);
3096 if (status == NFC_STATUS_OK) {
3097 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3098 }
3099
3100 return status;
3101 }
3102
3103 /*******************************************************************************
3104 **
3105 ** Function RW_I93LockBlock
3106 **
3107 ** Description This function send Lock Block command
3108 **
3109 ** RW_I93_CMD_CMPL_EVT will be returned
3110 **
3111 ** Returns NFC_STATUS_OK if success
3112 ** NFC_STATUS_NO_BUFFERS if out of buffer
3113 ** NFC_STATUS_BUSY if busy
3114 ** NFC_STATUS_FAILED if other error
3115 **
3116 *******************************************************************************/
RW_I93LockBlock(uint8_t block_number)3117 tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
3118 tNFC_STATUS status;
3119
3120 RW_TRACE_API0("RW_I93LockBlock ()");
3121
3122 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3123 RW_TRACE_ERROR1(
3124 "RW_I93LockBlock ():Unable to start command at state (0x%X)",
3125 rw_cb.tcb.i93.state);
3126 return NFC_STATUS_BUSY;
3127 }
3128
3129 status = rw_i93_send_cmd_lock_block(block_number);
3130 if (status == NFC_STATUS_OK) {
3131 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3132 }
3133
3134 return status;
3135 }
3136
3137 /*******************************************************************************
3138 **
3139 ** Function RW_I93ReadMultipleBlocks
3140 **
3141 ** Description This function send Read Multiple Blocks command
3142 **
3143 ** RW_I93_RESPONSE_EVT will be returned
3144 **
3145 ** Returns NFC_STATUS_OK if success
3146 ** NFC_STATUS_NO_BUFFERS if out of buffer
3147 ** NFC_STATUS_BUSY if busy
3148 ** NFC_STATUS_FAILED if other error
3149 **
3150 *******************************************************************************/
RW_I93ReadMultipleBlocks(uint16_t first_block_number,uint16_t number_blocks)3151 tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
3152 uint16_t number_blocks) {
3153 tNFC_STATUS status;
3154
3155 RW_TRACE_API0("RW_I93ReadMultipleBlocks ()");
3156
3157 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3158 RW_TRACE_ERROR1(
3159 "RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
3160 rw_cb.tcb.i93.state);
3161 return NFC_STATUS_BUSY;
3162 }
3163
3164 status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
3165 if (status == NFC_STATUS_OK) {
3166 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3167 }
3168
3169 return status;
3170 }
3171
3172 /*******************************************************************************
3173 **
3174 ** Function RW_I93WriteMultipleBlocks
3175 **
3176 ** Description This function send Write Multiple Blocks command
3177 **
3178 ** RW_I93_CMD_CMPL_EVT will be returned
3179 **
3180 ** Returns NFC_STATUS_OK if success
3181 ** NFC_STATUS_NO_BUFFERS if out of buffer
3182 ** NFC_STATUS_BUSY if busy
3183 ** NFC_STATUS_FAILED if other error
3184 **
3185 *******************************************************************************/
RW_I93WriteMultipleBlocks(uint8_t first_block_number,uint16_t number_blocks,uint8_t * p_data)3186 tNFC_STATUS RW_I93WriteMultipleBlocks(uint8_t first_block_number,
3187 uint16_t number_blocks, uint8_t* p_data) {
3188 tNFC_STATUS status;
3189
3190 RW_TRACE_API0("RW_I93WriteMultipleBlocks ()");
3191
3192 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3193 RW_TRACE_ERROR1(
3194 "RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
3195 rw_cb.tcb.i93.state);
3196 return NFC_STATUS_BUSY;
3197 }
3198
3199 if (rw_cb.tcb.i93.block_size == 0) {
3200 RW_TRACE_ERROR0("RW_I93WriteSingleBlock ():Block size is unknown");
3201 return NFC_STATUS_FAILED;
3202 }
3203
3204 status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
3205 p_data);
3206 if (status == NFC_STATUS_OK) {
3207 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3208 }
3209
3210 return status;
3211 }
3212
3213 /*******************************************************************************
3214 **
3215 ** Function RW_I93Select
3216 **
3217 ** Description This function send Select command
3218 **
3219 ** UID[0]: 0xE0, MSB
3220 ** UID[1]: IC Mfg Code
3221 ** ...
3222 ** UID[7]: LSB
3223 **
3224 ** RW_I93_CMD_CMPL_EVT will be returned
3225 **
3226 ** Returns NFC_STATUS_OK if success
3227 ** NFC_STATUS_NO_BUFFERS if out of buffer
3228 ** NFC_STATUS_BUSY if busy
3229 ** NFC_STATUS_FAILED if other error
3230 **
3231 *******************************************************************************/
RW_I93Select(uint8_t * p_uid)3232 tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
3233 tNFC_STATUS status;
3234
3235 RW_TRACE_API0("RW_I93Select ()");
3236
3237 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3238 RW_TRACE_ERROR1("RW_I93Select ():Unable to start command at state (0x%X)",
3239 rw_cb.tcb.i93.state);
3240 return NFC_STATUS_BUSY;
3241 }
3242
3243 if (p_uid) {
3244 status = rw_i93_send_cmd_select(p_uid);
3245 if (status == NFC_STATUS_OK) {
3246 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3247 }
3248 } else {
3249 RW_TRACE_ERROR0("RW_I93Select ():UID shall be provided");
3250 status = NFC_STATUS_FAILED;
3251 }
3252
3253 return status;
3254 }
3255
3256 /*******************************************************************************
3257 **
3258 ** Function RW_I93ResetToReady
3259 **
3260 ** Description This function send Reset To Ready command
3261 **
3262 ** RW_I93_CMD_CMPL_EVT will be returned
3263 **
3264 ** Returns NFC_STATUS_OK if success
3265 ** NFC_STATUS_NO_BUFFERS if out of buffer
3266 ** NFC_STATUS_BUSY if busy
3267 ** NFC_STATUS_FAILED if other error
3268 **
3269 *******************************************************************************/
RW_I93ResetToReady(void)3270 tNFC_STATUS RW_I93ResetToReady(void) {
3271 tNFC_STATUS status;
3272
3273 RW_TRACE_API0("RW_I93ResetToReady ()");
3274
3275 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3276 RW_TRACE_ERROR1(
3277 "RW_I93ResetToReady ():Unable to start command at state (0x%X)",
3278 rw_cb.tcb.i93.state);
3279 return NFC_STATUS_BUSY;
3280 }
3281
3282 status = rw_i93_send_cmd_reset_to_ready();
3283 if (status == NFC_STATUS_OK) {
3284 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3285 }
3286
3287 return status;
3288 }
3289
3290 /*******************************************************************************
3291 **
3292 ** Function RW_I93WriteAFI
3293 **
3294 ** Description This function send Write AFI command
3295 **
3296 ** RW_I93_CMD_CMPL_EVT will be returned
3297 **
3298 ** Returns NFC_STATUS_OK if success
3299 ** NFC_STATUS_NO_BUFFERS if out of buffer
3300 ** NFC_STATUS_BUSY if busy
3301 ** NFC_STATUS_FAILED if other error
3302 **
3303 *******************************************************************************/
RW_I93WriteAFI(uint8_t afi)3304 tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
3305 tNFC_STATUS status;
3306
3307 RW_TRACE_API0("RW_I93WriteAFI ()");
3308
3309 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3310 RW_TRACE_ERROR1("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
3311 rw_cb.tcb.i93.state);
3312 return NFC_STATUS_BUSY;
3313 }
3314
3315 status = rw_i93_send_cmd_write_afi(afi);
3316 if (status == NFC_STATUS_OK) {
3317 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3318 }
3319
3320 return status;
3321 }
3322
3323 /*******************************************************************************
3324 **
3325 ** Function RW_I93LockAFI
3326 **
3327 ** Description This function send Lock AFI command
3328 **
3329 ** RW_I93_CMD_CMPL_EVT will be returned
3330 **
3331 ** Returns NFC_STATUS_OK if success
3332 ** NFC_STATUS_NO_BUFFERS if out of buffer
3333 ** NFC_STATUS_BUSY if busy
3334 ** NFC_STATUS_FAILED if other error
3335 **
3336 *******************************************************************************/
RW_I93LockAFI(void)3337 tNFC_STATUS RW_I93LockAFI(void) {
3338 tNFC_STATUS status;
3339
3340 RW_TRACE_API0("RW_I93LockAFI ()");
3341
3342 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3343 RW_TRACE_ERROR1("RW_I93LockAFI ():Unable to start command at state (0x%X)",
3344 rw_cb.tcb.i93.state);
3345 return NFC_STATUS_BUSY;
3346 }
3347
3348 status = rw_i93_send_cmd_lock_afi();
3349 if (status == NFC_STATUS_OK) {
3350 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3351 }
3352
3353 return status;
3354 }
3355
3356 /*******************************************************************************
3357 **
3358 ** Function RW_I93WriteDSFID
3359 **
3360 ** Description This function send Write DSFID command
3361 **
3362 ** RW_I93_CMD_CMPL_EVT will be returned
3363 **
3364 ** Returns NFC_STATUS_OK if success
3365 ** NFC_STATUS_NO_BUFFERS if out of buffer
3366 ** NFC_STATUS_BUSY if busy
3367 ** NFC_STATUS_FAILED if other error
3368 **
3369 *******************************************************************************/
RW_I93WriteDSFID(uint8_t dsfid)3370 tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
3371 tNFC_STATUS status;
3372
3373 RW_TRACE_API0("RW_I93WriteDSFID ()");
3374
3375 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3376 RW_TRACE_ERROR1(
3377 "RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
3378 rw_cb.tcb.i93.state);
3379 return NFC_STATUS_BUSY;
3380 }
3381
3382 status = rw_i93_send_cmd_write_dsfid(dsfid);
3383 if (status == NFC_STATUS_OK) {
3384 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3385 }
3386
3387 return status;
3388 }
3389
3390 /*******************************************************************************
3391 **
3392 ** Function RW_I93LockDSFID
3393 **
3394 ** Description This function send Lock DSFID command
3395 **
3396 ** RW_I93_CMD_CMPL_EVT will be returned
3397 **
3398 ** Returns NFC_STATUS_OK if success
3399 ** NFC_STATUS_NO_BUFFERS if out of buffer
3400 ** NFC_STATUS_BUSY if busy
3401 ** NFC_STATUS_FAILED if other error
3402 **
3403 *******************************************************************************/
RW_I93LockDSFID(void)3404 tNFC_STATUS RW_I93LockDSFID(void) {
3405 tNFC_STATUS status;
3406
3407 RW_TRACE_API0("RW_I93LockDSFID ()");
3408
3409 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3410 RW_TRACE_ERROR1(
3411 "RW_I93LockDSFID ():Unable to start command at state (0x%X)",
3412 rw_cb.tcb.i93.state);
3413 return NFC_STATUS_BUSY;
3414 }
3415
3416 status = rw_i93_send_cmd_lock_dsfid();
3417 if (status == NFC_STATUS_OK) {
3418 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3419 }
3420
3421 return status;
3422 }
3423
3424 /*******************************************************************************
3425 **
3426 ** Function RW_I93GetSysInfo
3427 **
3428 ** Description This function send Get System Information command
3429 **
3430 ** RW_I93_RESPONSE_EVT will be returned
3431 **
3432 ** Returns NFC_STATUS_OK if success
3433 ** NFC_STATUS_NO_BUFFERS if out of buffer
3434 ** NFC_STATUS_BUSY if busy
3435 ** NFC_STATUS_FAILED if other error
3436 **
3437 *******************************************************************************/
RW_I93GetSysInfo(uint8_t * p_uid)3438 tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
3439 tNFC_STATUS status;
3440
3441 RW_TRACE_API0("RW_I93GetSysInfo ()");
3442
3443 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3444 RW_TRACE_ERROR1(
3445 "RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
3446 rw_cb.tcb.i93.state);
3447 return NFC_STATUS_BUSY;
3448 }
3449
3450 if (p_uid) {
3451 status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
3452 } else {
3453 status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
3454 }
3455
3456 if (status == NFC_STATUS_OK) {
3457 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3458 }
3459
3460 return status;
3461 }
3462
3463 /*******************************************************************************
3464 **
3465 ** Function RW_I93GetMultiBlockSecurityStatus
3466 **
3467 ** Description This function send Get Multiple Block Security Status
3468 ** command
3469 **
3470 ** RW_I93_RESPONSE_EVT will be returned
3471 **
3472 ** Returns NFC_STATUS_OK if success
3473 ** NFC_STATUS_NO_BUFFERS if out of buffer
3474 ** NFC_STATUS_BUSY if busy
3475 ** NFC_STATUS_FAILED if other error
3476 **
3477 *******************************************************************************/
RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,uint16_t number_blocks)3478 tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
3479 uint16_t number_blocks) {
3480 tNFC_STATUS status;
3481
3482 RW_TRACE_API0("RW_I93GetMultiBlockSecurityStatus ()");
3483
3484 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3485 RW_TRACE_ERROR1(
3486 "RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state "
3487 "(0x%X)",
3488 rw_cb.tcb.i93.state);
3489 return NFC_STATUS_BUSY;
3490 }
3491
3492 status =
3493 rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
3494 if (status == NFC_STATUS_OK) {
3495 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3496 }
3497
3498 return status;
3499 }
3500
3501 /*******************************************************************************
3502 **
3503 ** Function RW_I93DetectNDef
3504 **
3505 ** Description This function performs NDEF detection procedure
3506 **
3507 ** RW_I93_NDEF_DETECT_EVT will be returned
3508 **
3509 ** Returns NFC_STATUS_OK if success
3510 ** NFC_STATUS_FAILED if busy or other error
3511 **
3512 *******************************************************************************/
RW_I93DetectNDef(void)3513 tNFC_STATUS RW_I93DetectNDef(void) {
3514 tNFC_STATUS status;
3515 tRW_I93_RW_SUBSTATE sub_state;
3516
3517 RW_TRACE_API0("RW_I93DetectNDef ()");
3518
3519 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3520 RW_TRACE_ERROR1(
3521 "RW_I93DetectNDef ():Unable to start command at state (0x%X)",
3522 rw_cb.tcb.i93.state);
3523 return NFC_STATUS_FAILED;
3524 }
3525
3526 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
3527 status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
3528 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3529 } else if ((rw_cb.tcb.i93.num_block == 0) ||
3530 (rw_cb.tcb.i93.block_size == 0)) {
3531 status =
3532 rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3533 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
3534
3535 /* clear all flags */
3536 rw_cb.tcb.i93.intl_flags = 0;
3537 } else {
3538 /* read CC in the first block */
3539 status = rw_i93_send_cmd_read_single_block(0x0000, false);
3540 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3541 }
3542
3543 if (status == NFC_STATUS_OK) {
3544 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3545 rw_cb.tcb.i93.sub_state = sub_state;
3546
3547 /* clear flags except flag for 2 bytes of number of blocks */
3548 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3549 }
3550
3551 return (status);
3552 }
3553
3554 /*******************************************************************************
3555 **
3556 ** Function RW_I93ReadNDef
3557 **
3558 ** Description This function performs NDEF read procedure
3559 ** Note: RW_I93DetectNDef () must be called before using this
3560 **
3561 ** The following event will be returned
3562 ** RW_I93_NDEF_READ_EVT for each segmented NDEF message
3563 ** RW_I93_NDEF_READ_CPLT_EVT for the last segment or
3564 ** complete NDEF
3565 ** RW_I93_NDEF_READ_FAIL_EVT for failure
3566 **
3567 ** Returns NFC_STATUS_OK if success
3568 ** NFC_STATUS_FAILED if I93 is busy or other error
3569 **
3570 *******************************************************************************/
RW_I93ReadNDef(void)3571 tNFC_STATUS RW_I93ReadNDef(void) {
3572 RW_TRACE_API0("RW_I93ReadNDef ()");
3573
3574 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3575 RW_TRACE_ERROR1("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
3576 rw_cb.tcb.i93.state);
3577 return NFC_STATUS_FAILED;
3578 }
3579
3580 if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
3581 (rw_cb.tcb.i93.ndef_length > 0)) {
3582 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3583 rw_cb.tcb.i93.rw_length = 0;
3584
3585 if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
3586 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3587 } else {
3588 return NFC_STATUS_FAILED;
3589 }
3590 } else {
3591 RW_TRACE_ERROR0("RW_I93ReadNDef ():No NDEF detected");
3592 return NFC_STATUS_FAILED;
3593 }
3594
3595 return NFC_STATUS_OK;
3596 }
3597
3598 /*******************************************************************************
3599 **
3600 ** Function RW_I93UpdateNDef
3601 **
3602 ** Description This function performs NDEF update procedure
3603 ** Note: RW_I93DetectNDef () must be called before using this
3604 ** Updating data must not be removed until returning
3605 ** event
3606 **
3607 ** The following event will be returned
3608 ** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3609 ** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3610 **
3611 ** Returns NFC_STATUS_OK if success
3612 ** NFC_STATUS_FAILED if I93 is busy or other error
3613 **
3614 *******************************************************************************/
RW_I93UpdateNDef(uint16_t length,uint8_t * p_data)3615 tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
3616 uint16_t block_number;
3617
3618 RW_TRACE_API1("RW_I93UpdateNDef () length:%d", length);
3619
3620 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3621 RW_TRACE_ERROR1(
3622 "RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
3623 rw_cb.tcb.i93.state);
3624 return NFC_STATUS_FAILED;
3625 }
3626
3627 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3628 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
3629 RW_TRACE_ERROR0("RW_I93UpdateNDef ():NDEF is read-only");
3630 return NFC_STATUS_FAILED;
3631 }
3632 if (rw_cb.tcb.i93.max_ndef_length < length) {
3633 RW_TRACE_ERROR2(
3634 "RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length "
3635 "(%d)",
3636 length, rw_cb.tcb.i93.max_ndef_length);
3637 return NFC_STATUS_FAILED;
3638 }
3639
3640 rw_cb.tcb.i93.ndef_length = length;
3641 rw_cb.tcb.i93.p_update_data = p_data;
3642
3643 /* read length field */
3644 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3645 rw_cb.tcb.i93.rw_length = 0;
3646
3647 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
3648
3649 if (rw_i93_send_cmd_read_single_block(block_number, false) ==
3650 NFC_STATUS_OK) {
3651 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3652 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3653 } else {
3654 return NFC_STATUS_FAILED;
3655 }
3656 } else {
3657 RW_TRACE_ERROR0("RW_I93ReadNDef ():No NDEF detected");
3658 return NFC_STATUS_FAILED;
3659 }
3660
3661 return NFC_STATUS_OK;
3662 }
3663
3664 /*******************************************************************************
3665 **
3666 ** Function RW_I93FormatNDef
3667 **
3668 ** Description This function performs formatting procedure
3669 **
3670 ** RW_I93_FORMAT_CPLT_EVT will be returned
3671 **
3672 ** Returns NFC_STATUS_OK if success
3673 ** NFC_STATUS_FAILED if busy or other error
3674 **
3675 *******************************************************************************/
RW_I93FormatNDef(void)3676 tNFC_STATUS RW_I93FormatNDef(void) {
3677 tNFC_STATUS status;
3678 tRW_I93_RW_SUBSTATE sub_state;
3679
3680 RW_TRACE_API0("RW_I93FormatNDef ()");
3681
3682 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3683 RW_TRACE_ERROR1(
3684 "RW_I93FormatNDef ():Unable to start command at state (0x%X)",
3685 rw_cb.tcb.i93.state);
3686 return NFC_STATUS_FAILED;
3687 }
3688
3689 if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
3690 (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
3691 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
3692 */
3693 rw_cb.tcb.i93.rw_offset = 0;
3694
3695 /* read blocks with option flag to get block security status */
3696 status = rw_i93_send_cmd_read_single_block(0x0000, true);
3697 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
3698 } else {
3699 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3700 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3701 }
3702
3703 if (status == NFC_STATUS_OK) {
3704 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
3705 rw_cb.tcb.i93.sub_state = sub_state;
3706 rw_cb.tcb.i93.intl_flags = 0;
3707 }
3708
3709 return (status);
3710 }
3711
3712 /*******************************************************************************
3713 **
3714 ** Function RW_I93SetTagReadOnly
3715 **
3716 ** Description This function performs NDEF read-only procedure
3717 ** Note: RW_I93DetectNDef () must be called before using this
3718 ** Updating data must not be removed until returning
3719 ** event
3720 **
3721 ** The RW_I93_SET_TAG_RO_EVT event will be returned.
3722 **
3723 ** Returns NFC_STATUS_OK if success
3724 ** NFC_STATUS_FAILED if I93 is busy or other error
3725 **
3726 *******************************************************************************/
RW_I93SetTagReadOnly(void)3727 tNFC_STATUS RW_I93SetTagReadOnly(void) {
3728 RW_TRACE_API0("RW_I93SetTagReadOnly ()");
3729
3730 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3731 RW_TRACE_ERROR1(
3732 "RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
3733 rw_cb.tcb.i93.state);
3734 return NFC_STATUS_FAILED;
3735 }
3736
3737 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
3738 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
3739 RW_TRACE_ERROR0("RW_I93SetTagReadOnly ():NDEF is already read-only");
3740 return NFC_STATUS_FAILED;
3741 }
3742
3743 /* get CC in the first block */
3744 if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
3745 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
3746 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
3747 } else {
3748 return NFC_STATUS_FAILED;
3749 }
3750 } else {
3751 RW_TRACE_ERROR0("RW_I93SetTagReadOnly ():No NDEF detected");
3752 return NFC_STATUS_FAILED;
3753 }
3754
3755 return NFC_STATUS_OK;
3756 }
3757
3758 /*****************************************************************************
3759 **
3760 ** Function RW_I93PresenceCheck
3761 **
3762 ** Description Check if the tag is still in the field.
3763 **
3764 ** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
3765 ** presence or non-presence.
3766 **
3767 ** Returns NFC_STATUS_OK, if raw data frame sent
3768 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
3769 ** operation
3770 ** NFC_STATUS_FAILED: other error
3771 **
3772 *****************************************************************************/
RW_I93PresenceCheck(void)3773 tNFC_STATUS RW_I93PresenceCheck(void) {
3774 tNFC_STATUS status;
3775 tRW_DATA evt_data;
3776
3777 RW_TRACE_API0("RW_I93PresenceCheck ()");
3778
3779 if (!rw_cb.p_cback) {
3780 return NFC_STATUS_FAILED;
3781 } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
3782 evt_data.status = NFC_STATUS_FAILED;
3783 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
3784
3785 return NFC_STATUS_OK;
3786 } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
3787 return NFC_STATUS_BUSY;
3788 } else {
3789 /* The support of AFI by the VICC is optional, so do not include AFI */
3790 status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
3791
3792 if (status == NFC_STATUS_OK) {
3793 /* do not retry during presence check */
3794 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
3795 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
3796 }
3797 }
3798
3799 return (status);
3800 }
3801
3802 #if (BT_TRACE_VERBOSE == TRUE)
3803 /*******************************************************************************
3804 **
3805 ** Function rw_i93_get_state_name
3806 **
3807 ** Description This function returns the state name.
3808 **
3809 ** NOTE conditionally compiled to save memory.
3810 **
3811 ** Returns pointer to the name
3812 **
3813 *******************************************************************************/
rw_i93_get_state_name(uint8_t state)3814 static char* rw_i93_get_state_name(uint8_t state) {
3815 switch (state) {
3816 case RW_I93_STATE_NOT_ACTIVATED:
3817 return ("NOT_ACTIVATED");
3818 case RW_I93_STATE_IDLE:
3819 return ("IDLE");
3820 case RW_I93_STATE_BUSY:
3821 return ("BUSY");
3822
3823 case RW_I93_STATE_DETECT_NDEF:
3824 return ("NDEF_DETECTION");
3825 case RW_I93_STATE_READ_NDEF:
3826 return ("READ_NDEF");
3827 case RW_I93_STATE_UPDATE_NDEF:
3828 return ("UPDATE_NDEF");
3829 case RW_I93_STATE_FORMAT:
3830 return ("FORMAT");
3831 case RW_I93_STATE_SET_READ_ONLY:
3832 return ("SET_READ_ONLY");
3833
3834 case RW_I93_STATE_PRESENCE_CHECK:
3835 return ("PRESENCE_CHECK");
3836 default:
3837 return ("???? UNKNOWN STATE");
3838 }
3839 }
3840
3841 /*******************************************************************************
3842 **
3843 ** Function rw_i93_get_sub_state_name
3844 **
3845 ** Description This function returns the sub_state name.
3846 **
3847 ** NOTE conditionally compiled to save memory.
3848 **
3849 ** Returns pointer to the name
3850 **
3851 *******************************************************************************/
rw_i93_get_sub_state_name(uint8_t sub_state)3852 static char* rw_i93_get_sub_state_name(uint8_t sub_state) {
3853 switch (sub_state) {
3854 case RW_I93_SUBSTATE_WAIT_UID:
3855 return ("WAIT_UID");
3856 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
3857 return ("WAIT_SYS_INFO");
3858 case RW_I93_SUBSTATE_WAIT_CC:
3859 return ("WAIT_CC");
3860 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
3861 return ("SEARCH_NDEF_TLV");
3862 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
3863 return ("CHECK_LOCK_STATUS");
3864 case RW_I93_SUBSTATE_RESET_LEN:
3865 return ("RESET_LEN");
3866 case RW_I93_SUBSTATE_WRITE_NDEF:
3867 return ("WRITE_NDEF");
3868 case RW_I93_SUBSTATE_UPDATE_LEN:
3869 return ("UPDATE_LEN");
3870 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
3871 return ("WAIT_RESET_DSFID_AFI");
3872 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
3873 return ("CHECK_READ_ONLY");
3874 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
3875 return ("WRITE_CC_NDEF_TLV");
3876 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
3877 return ("WAIT_UPDATE_CC");
3878 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
3879 return ("LOCK_NDEF_TLV");
3880 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
3881 return ("WAIT_LOCK_CC");
3882 default:
3883 return ("???? UNKNOWN SUBSTATE");
3884 }
3885 }
3886
3887 /*******************************************************************************
3888 **
3889 ** Function rw_i93_get_tag_name
3890 **
3891 ** Description This function returns the tag name.
3892 **
3893 ** NOTE conditionally compiled to save memory.
3894 **
3895 ** Returns pointer to the name
3896 **
3897 *******************************************************************************/
rw_i93_get_tag_name(uint8_t product_version)3898 static char* rw_i93_get_tag_name(uint8_t product_version) {
3899 switch (product_version) {
3900 case RW_I93_ICODE_SLI:
3901 return ("SLI/SLIX");
3902 case RW_I93_ICODE_SLI_S:
3903 return ("SLI-S/SLIX-S");
3904 case RW_I93_ICODE_SLI_L:
3905 return ("SLI-L/SLIX-L");
3906 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
3907 return ("Tag-it HF-I Plus Inlay");
3908 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
3909 return ("Tag-it HF-I Plus Chip");
3910 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
3911 return ("Tag-it HF-I Standard Chip/Inlyas");
3912 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
3913 return ("Tag-it HF-I Pro Chip/Inlays");
3914 case RW_I93_STM_LRI1K:
3915 return ("LRi1K");
3916 case RW_I93_STM_LRI2K:
3917 return ("LRi2K");
3918 case RW_I93_STM_LRIS2K:
3919 return ("LRiS2K");
3920 case RW_I93_STM_LRIS64K:
3921 return ("LRiS64K");
3922 case RW_I93_STM_M24LR64_R:
3923 return ("M24LR64");
3924 case RW_I93_STM_M24LR04E_R:
3925 return ("M24LR04E");
3926 case RW_I93_STM_M24LR16E_R:
3927 return ("M24LR16E");
3928 case RW_I93_STM_M24LR64E_R:
3929 return ("M24LR64E");
3930 case RW_I93_UNKNOWN_PRODUCT:
3931 default:
3932 return ("UNKNOWN");
3933 }
3934 }
3935
3936 #endif
3937