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