1 /******************************************************************************
2 *
3 * Copyright (C) 2011-2014 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19
20 /******************************************************************************
21 *
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
3007 if (rw_i93_send_to_lower (p_buf))
3008 {
3009 return;
3010 }
3011 }
3012
3013 /* all retrial is done or failed to send command to lower layer */
3014 if (rw_cb.tcb.i93.p_retry_cmd)
3015 {
3016 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
3017 rw_cb.tcb.i93.p_retry_cmd = NULL;
3018 rw_cb.tcb.i93.retry_count = 0;
3019 }
3020 rw_i93_handle_error (NFC_STATUS_TIMEOUT);
3021 }
3022 else
3023 {
3024 RW_TRACE_ERROR1 ("rw_i93_process_timeout () unknown event=%d", p_tle->event);
3025 }
3026 }
3027
3028 /*******************************************************************************
3029 **
3030 ** Function rw_i93_data_cback
3031 **
3032 ** Description This callback function receives the data from NFCC.
3033 **
3034 ** Returns none
3035 **
3036 *******************************************************************************/
rw_i93_data_cback(UINT8 conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)3037 static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
3038 {
3039 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
3040 BT_HDR *p_resp;
3041 tRW_DATA rw_data;
3042
3043 #if (BT_TRACE_VERBOSE == TRUE)
3044 UINT8 begin_state = p_i93->state;
3045 #endif
3046
3047 RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
3048
3049 if ( (event == NFC_DEACTIVATE_CEVT)
3050 ||(event == NFC_ERROR_CEVT) )
3051 {
3052 nfc_stop_quick_timer (&p_i93->timer);
3053
3054 if (event == NFC_ERROR_CEVT)
3055 {
3056 if ( (p_i93->retry_count < RW_MAX_RETRIES)
3057 &&(p_i93->p_retry_cmd) )
3058 {
3059 p_i93->retry_count++;
3060
3061 RW_TRACE_ERROR1 ("rw_i93_data_cback (): retry_count = %d", p_i93->retry_count);
3062
3063 p_resp = p_i93->p_retry_cmd;
3064 p_i93->p_retry_cmd = NULL;
3065 if (rw_i93_send_to_lower (p_resp))
3066 {
3067 return;
3068 }
3069 }
3070
3071 /* all retrial is done or failed to send command to lower layer */
3072 if (p_i93->p_retry_cmd)
3073 {
3074 GKI_freebuf (p_i93->p_retry_cmd);
3075 p_i93->p_retry_cmd = NULL;
3076 p_i93->retry_count = 0;
3077 }
3078
3079 rw_i93_handle_error ((tNFC_STATUS) (*(UINT8*) p_data));
3080 }
3081 else
3082 {
3083 /* free retry buffer */
3084 if (p_i93->p_retry_cmd)
3085 {
3086 GKI_freebuf (p_i93->p_retry_cmd);
3087 p_i93->p_retry_cmd = NULL;
3088 p_i93->retry_count = 0;
3089 }
3090 NFC_SetStaticRfCback (NULL);
3091 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
3092 }
3093 return;
3094 }
3095
3096 if (event != NFC_DATA_CEVT)
3097 {
3098 return;
3099 }
3100
3101 p_resp = (BT_HDR *) p_data->data.p_data;
3102
3103 nfc_stop_quick_timer (&p_i93->timer);
3104
3105 /* free retry buffer */
3106 if (p_i93->p_retry_cmd)
3107 {
3108 GKI_freebuf (p_i93->p_retry_cmd);
3109 p_i93->p_retry_cmd = NULL;
3110 p_i93->retry_count = 0;
3111 }
3112
3113 #if (BT_TRACE_PROTOCOL == TRUE)
3114 DispRWI93Tag (p_resp, TRUE, p_i93->sent_cmd);
3115 #endif
3116
3117 #if (BT_TRACE_VERBOSE == TRUE)
3118 RW_TRACE_DEBUG2 ("RW I93 state: <%s (%d)>",
3119 rw_i93_get_state_name (p_i93->state), p_i93->state);
3120 #else
3121 RW_TRACE_DEBUG1 ("RW I93 state: %d", p_i93->state);
3122 #endif
3123
3124 switch (p_i93->state)
3125 {
3126 case RW_I93_STATE_IDLE:
3127 /* Unexpected Response from VICC, it should be raw frame response */
3128 /* forward to upper layer without parsing */
3129 p_i93->sent_cmd = 0;
3130 if (rw_cb.p_cback)
3131 {
3132 rw_data.raw_frame.status = p_data->data.status;
3133 rw_data.raw_frame.p_data = p_resp;
3134 (*(rw_cb.p_cback)) (RW_I93_RAW_FRAME_EVT, &rw_data);
3135 p_resp = NULL;
3136 }
3137 else
3138 {
3139 GKI_freebuf (p_resp);
3140 }
3141 break;
3142 case RW_I93_STATE_BUSY:
3143 p_i93->state = RW_I93_STATE_IDLE;
3144 rw_i93_send_to_upper (p_resp);
3145 GKI_freebuf (p_resp);
3146 break;
3147
3148 case RW_I93_STATE_DETECT_NDEF:
3149 rw_i93_sm_detect_ndef (p_resp);
3150 GKI_freebuf (p_resp);
3151 break;
3152
3153 case RW_I93_STATE_READ_NDEF:
3154 rw_i93_sm_read_ndef (p_resp);
3155 /* p_resp may send upper lyaer */
3156 break;
3157
3158 case RW_I93_STATE_UPDATE_NDEF:
3159 rw_i93_sm_update_ndef (p_resp);
3160 GKI_freebuf (p_resp);
3161 break;
3162
3163 case RW_I93_STATE_FORMAT:
3164 rw_i93_sm_format (p_resp);
3165 GKI_freebuf (p_resp);
3166 break;
3167
3168 case RW_I93_STATE_SET_READ_ONLY:
3169 rw_i93_sm_set_read_only (p_resp);
3170 GKI_freebuf (p_resp);
3171 break;
3172
3173 case RW_I93_STATE_PRESENCE_CHECK:
3174 p_i93->state = RW_I93_STATE_IDLE;
3175 p_i93->sent_cmd = 0;
3176
3177 /* if any response, send presence check with ok */
3178 rw_data.status = NFC_STATUS_OK;
3179 (*(rw_cb.p_cback)) (RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3180 GKI_freebuf (p_resp);
3181 break;
3182
3183 default:
3184 RW_TRACE_ERROR1 ("rw_i93_data_cback (): invalid state=%d", p_i93->state);
3185 GKI_freebuf (p_resp);
3186 break;
3187 }
3188
3189 #if (BT_TRACE_VERBOSE == TRUE)
3190 if (begin_state != p_i93->state)
3191 {
3192 RW_TRACE_DEBUG2 ("RW I93 state changed:<%s> -> <%s>",
3193 rw_i93_get_state_name (begin_state),
3194 rw_i93_get_state_name (p_i93->state));
3195 }
3196 #endif
3197 }
3198
3199 /*******************************************************************************
3200 **
3201 ** Function rw_i93_select
3202 **
3203 ** Description Initialise ISO 15693 RW
3204 **
3205 ** Returns NFC_STATUS_OK if success
3206 **
3207 *******************************************************************************/
rw_i93_select(UINT8 * p_uid)3208 tNFC_STATUS rw_i93_select (UINT8 *p_uid)
3209 {
3210 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
3211 UINT8 uid[I93_UID_BYTE_LEN], *p;
3212
3213 RW_TRACE_DEBUG0 ("rw_i93_select ()");
3214
3215 NFC_SetStaticRfCback (rw_i93_data_cback);
3216
3217 p_i93->state = RW_I93_STATE_IDLE;
3218
3219 /* convert UID to big endian format - MSB(0xE0) in first byte */
3220 p = uid;
3221 STREAM_TO_ARRAY8 (p, p_uid);
3222
3223 rw_i93_get_product_version (uid);
3224
3225 return NFC_STATUS_OK;
3226 }
3227
3228 /*******************************************************************************
3229 **
3230 ** Function RW_I93Inventory
3231 **
3232 ** Description This function send Inventory command with/without AFI
3233 ** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3234 **
3235 ** RW_I93_RESPONSE_EVT will be returned
3236 **
3237 ** Returns NFC_STATUS_OK if success
3238 ** NFC_STATUS_NO_BUFFERS if out of buffer
3239 ** NFC_STATUS_BUSY if busy
3240 ** NFC_STATUS_FAILED if other error
3241 **
3242 *******************************************************************************/
RW_I93Inventory(BOOLEAN including_afi,UINT8 afi,UINT8 * p_uid)3243 tNFC_STATUS RW_I93Inventory (BOOLEAN including_afi, UINT8 afi, UINT8 *p_uid)
3244 {
3245 tNFC_STATUS status;
3246
3247 RW_TRACE_API2 ("RW_I93Inventory (), including_afi:%d, AFI:0x%02X", including_afi, afi);
3248
3249 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3250 {
3251 RW_TRACE_ERROR1 ("RW_I93Inventory ():Unable to start command at state (0x%X)",
3252 rw_cb.tcb.i93.state);
3253 return NFC_STATUS_BUSY;
3254 }
3255
3256 status = rw_i93_send_cmd_inventory (p_uid, including_afi, afi);
3257
3258 if (status == NFC_STATUS_OK)
3259 {
3260 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3261 }
3262
3263 return (status);
3264 }
3265
3266 /*******************************************************************************
3267 **
3268 ** Function RW_I93StayQuiet
3269 **
3270 ** Description This function send Inventory command
3271 **
3272 ** RW_I93_CMD_CMPL_EVT will be returned
3273 **
3274 ** Returns NFC_STATUS_OK if success
3275 ** NFC_STATUS_NO_BUFFERS if out of buffer
3276 ** NFC_STATUS_BUSY if busy
3277 ** NFC_STATUS_FAILED if other error
3278 **
3279 *******************************************************************************/
RW_I93StayQuiet(void)3280 tNFC_STATUS RW_I93StayQuiet (void)
3281 {
3282 tNFC_STATUS status;
3283
3284 RW_TRACE_API0 ("RW_I93StayQuiet ()");
3285
3286 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3287 {
3288 RW_TRACE_ERROR1 ("RW_I93StayQuiet ():Unable to start command at state (0x%X)",
3289 rw_cb.tcb.i93.state);
3290 return NFC_STATUS_BUSY;
3291 }
3292
3293 status = rw_i93_send_cmd_stay_quiet ();
3294 if (status == NFC_STATUS_OK)
3295 {
3296 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3297 }
3298
3299 return status;
3300 }
3301
3302 /*******************************************************************************
3303 **
3304 ** Function RW_I93ReadSingleBlock
3305 **
3306 ** Description This function send Read Single Block command
3307 **
3308 ** RW_I93_RESPONSE_EVT will be returned
3309 **
3310 ** Returns NFC_STATUS_OK if success
3311 ** NFC_STATUS_NO_BUFFERS if out of buffer
3312 ** NFC_STATUS_BUSY if busy
3313 ** NFC_STATUS_FAILED if other error
3314 **
3315 *******************************************************************************/
RW_I93ReadSingleBlock(UINT16 block_number)3316 tNFC_STATUS RW_I93ReadSingleBlock (UINT16 block_number)
3317 {
3318 tNFC_STATUS status;
3319
3320 RW_TRACE_API1 ("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
3321
3322 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3323 {
3324 RW_TRACE_ERROR1 ("RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
3325 rw_cb.tcb.i93.state);
3326 return NFC_STATUS_BUSY;
3327 }
3328
3329 status = rw_i93_send_cmd_read_single_block (block_number, FALSE);
3330 if (status == NFC_STATUS_OK)
3331 {
3332 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3333 }
3334
3335 return status;
3336 }
3337
3338 /*******************************************************************************
3339 **
3340 ** Function RW_I93WriteSingleBlock
3341 **
3342 ** Description This function send Write Single Block command
3343 ** Application must get block size first by calling RW_I93GetSysInfo().
3344 **
3345 ** RW_I93_CMD_CMPL_EVT will be returned
3346 **
3347 ** Returns NFC_STATUS_OK if success
3348 ** NFC_STATUS_NO_BUFFERS if out of buffer
3349 ** NFC_STATUS_BUSY if busy
3350 ** NFC_STATUS_FAILED if other error
3351 **
3352 *******************************************************************************/
RW_I93WriteSingleBlock(UINT16 block_number,UINT8 * p_data)3353 tNFC_STATUS RW_I93WriteSingleBlock (UINT16 block_number,
3354 UINT8 *p_data)
3355 {
3356 tNFC_STATUS status;
3357
3358 RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
3359
3360 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3361 {
3362 RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
3363 rw_cb.tcb.i93.state);
3364 return NFC_STATUS_BUSY;
3365 }
3366
3367 if (rw_cb.tcb.i93.block_size == 0)
3368 {
3369 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3370 return NFC_STATUS_FAILED;
3371 }
3372
3373 status = rw_i93_send_cmd_write_single_block (block_number, p_data);
3374 if (status == NFC_STATUS_OK)
3375 {
3376 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3377 }
3378
3379 return status;
3380 }
3381
3382 /*******************************************************************************
3383 **
3384 ** Function RW_I93LockBlock
3385 **
3386 ** Description This function send Lock Block command
3387 **
3388 ** RW_I93_CMD_CMPL_EVT will be returned
3389 **
3390 ** Returns NFC_STATUS_OK if success
3391 ** NFC_STATUS_NO_BUFFERS if out of buffer
3392 ** NFC_STATUS_BUSY if busy
3393 ** NFC_STATUS_FAILED if other error
3394 **
3395 *******************************************************************************/
RW_I93LockBlock(UINT8 block_number)3396 tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
3397 {
3398 tNFC_STATUS status;
3399
3400 RW_TRACE_API0 ("RW_I93LockBlock ()");
3401
3402 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3403 {
3404 RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
3405 rw_cb.tcb.i93.state);
3406 return NFC_STATUS_BUSY;
3407 }
3408
3409 status = rw_i93_send_cmd_lock_block (block_number);
3410 if (status == NFC_STATUS_OK)
3411 {
3412 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3413 }
3414
3415 return status;
3416 }
3417
3418 /*******************************************************************************
3419 **
3420 ** Function RW_I93ReadMultipleBlocks
3421 **
3422 ** Description This function send Read Multiple Blocks command
3423 **
3424 ** RW_I93_RESPONSE_EVT will be returned
3425 **
3426 ** Returns NFC_STATUS_OK if success
3427 ** NFC_STATUS_NO_BUFFERS if out of buffer
3428 ** NFC_STATUS_BUSY if busy
3429 ** NFC_STATUS_FAILED if other error
3430 **
3431 *******************************************************************************/
RW_I93ReadMultipleBlocks(UINT16 first_block_number,UINT16 number_blocks)3432 tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
3433 UINT16 number_blocks)
3434 {
3435 tNFC_STATUS status;
3436
3437 RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
3438
3439 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3440 {
3441 RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
3442 rw_cb.tcb.i93.state);
3443 return NFC_STATUS_BUSY;
3444 }
3445
3446 status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
3447 if (status == NFC_STATUS_OK)
3448 {
3449 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3450 }
3451
3452 return status;
3453 }
3454
3455 /*******************************************************************************
3456 **
3457 ** Function RW_I93WriteMultipleBlocks
3458 **
3459 ** Description This function send Write Multiple Blocks command
3460 **
3461 ** RW_I93_CMD_CMPL_EVT will be returned
3462 **
3463 ** Returns NFC_STATUS_OK if success
3464 ** NFC_STATUS_NO_BUFFERS if out of buffer
3465 ** NFC_STATUS_BUSY if busy
3466 ** NFC_STATUS_FAILED if other error
3467 **
3468 *******************************************************************************/
RW_I93WriteMultipleBlocks(UINT8 first_block_number,UINT16 number_blocks,UINT8 * p_data)3469 tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
3470 UINT16 number_blocks,
3471 UINT8 *p_data)
3472 {
3473 tNFC_STATUS status;
3474
3475 RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
3476
3477 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3478 {
3479 RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
3480 rw_cb.tcb.i93.state);
3481 return NFC_STATUS_BUSY;
3482 }
3483
3484 if (rw_cb.tcb.i93.block_size == 0)
3485 {
3486 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3487 return NFC_STATUS_FAILED;
3488 }
3489
3490 status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
3491 if (status == NFC_STATUS_OK)
3492 {
3493 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3494 }
3495
3496 return status;
3497 }
3498
3499 /*******************************************************************************
3500 **
3501 ** Function RW_I93Select
3502 **
3503 ** Description This function send Select command
3504 **
3505 ** UID[0]: 0xE0, MSB
3506 ** UID[1]: IC Mfg Code
3507 ** ...
3508 ** UID[7]: LSB
3509 **
3510 ** RW_I93_CMD_CMPL_EVT will be returned
3511 **
3512 ** Returns NFC_STATUS_OK if success
3513 ** NFC_STATUS_NO_BUFFERS if out of buffer
3514 ** NFC_STATUS_BUSY if busy
3515 ** NFC_STATUS_FAILED if other error
3516 **
3517 *******************************************************************************/
RW_I93Select(UINT8 * p_uid)3518 tNFC_STATUS RW_I93Select (UINT8 *p_uid)
3519 {
3520 tNFC_STATUS status;
3521
3522 RW_TRACE_API0 ("RW_I93Select ()");
3523
3524 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3525 {
3526 RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
3527 rw_cb.tcb.i93.state);
3528 return NFC_STATUS_BUSY;
3529 }
3530
3531 if (p_uid)
3532 {
3533 status = rw_i93_send_cmd_select (p_uid);
3534 if (status == NFC_STATUS_OK)
3535 {
3536 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3537 }
3538 }
3539 else
3540 {
3541 RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
3542 status = NFC_STATUS_FAILED;
3543 }
3544
3545 return status;
3546 }
3547
3548 /*******************************************************************************
3549 **
3550 ** Function RW_I93ResetToReady
3551 **
3552 ** Description This function send Reset To Ready command
3553 **
3554 ** RW_I93_CMD_CMPL_EVT will be returned
3555 **
3556 ** Returns NFC_STATUS_OK if success
3557 ** NFC_STATUS_NO_BUFFERS if out of buffer
3558 ** NFC_STATUS_BUSY if busy
3559 ** NFC_STATUS_FAILED if other error
3560 **
3561 *******************************************************************************/
RW_I93ResetToReady(void)3562 tNFC_STATUS RW_I93ResetToReady (void)
3563 {
3564 tNFC_STATUS status;
3565
3566 RW_TRACE_API0 ("RW_I93ResetToReady ()");
3567
3568 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3569 {
3570 RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
3571 rw_cb.tcb.i93.state);
3572 return NFC_STATUS_BUSY;
3573 }
3574
3575 status = rw_i93_send_cmd_reset_to_ready ();
3576 if (status == NFC_STATUS_OK)
3577 {
3578 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3579 }
3580
3581 return status;
3582 }
3583
3584 /*******************************************************************************
3585 **
3586 ** Function RW_I93WriteAFI
3587 **
3588 ** Description This function send Write AFI command
3589 **
3590 ** RW_I93_CMD_CMPL_EVT will be returned
3591 **
3592 ** Returns NFC_STATUS_OK if success
3593 ** NFC_STATUS_NO_BUFFERS if out of buffer
3594 ** NFC_STATUS_BUSY if busy
3595 ** NFC_STATUS_FAILED if other error
3596 **
3597 *******************************************************************************/
RW_I93WriteAFI(UINT8 afi)3598 tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
3599 {
3600 tNFC_STATUS status;
3601
3602 RW_TRACE_API0 ("RW_I93WriteAFI ()");
3603
3604 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3605 {
3606 RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
3607 rw_cb.tcb.i93.state);
3608 return NFC_STATUS_BUSY;
3609 }
3610
3611 status = rw_i93_send_cmd_write_afi (afi);
3612 if (status == NFC_STATUS_OK)
3613 {
3614 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3615 }
3616
3617 return status;
3618 }
3619
3620 /*******************************************************************************
3621 **
3622 ** Function RW_I93LockAFI
3623 **
3624 ** Description This function send Lock AFI command
3625 **
3626 ** RW_I93_CMD_CMPL_EVT will be returned
3627 **
3628 ** Returns NFC_STATUS_OK if success
3629 ** NFC_STATUS_NO_BUFFERS if out of buffer
3630 ** NFC_STATUS_BUSY if busy
3631 ** NFC_STATUS_FAILED if other error
3632 **
3633 *******************************************************************************/
RW_I93LockAFI(void)3634 tNFC_STATUS RW_I93LockAFI (void)
3635 {
3636 tNFC_STATUS status;
3637
3638 RW_TRACE_API0 ("RW_I93LockAFI ()");
3639
3640 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3641 {
3642 RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
3643 rw_cb.tcb.i93.state);
3644 return NFC_STATUS_BUSY;
3645 }
3646
3647 status = rw_i93_send_cmd_lock_afi ();
3648 if (status == NFC_STATUS_OK)
3649 {
3650 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3651 }
3652
3653 return status;
3654 }
3655
3656 /*******************************************************************************
3657 **
3658 ** Function RW_I93WriteDSFID
3659 **
3660 ** Description This function send Write DSFID command
3661 **
3662 ** RW_I93_CMD_CMPL_EVT will be returned
3663 **
3664 ** Returns NFC_STATUS_OK if success
3665 ** NFC_STATUS_NO_BUFFERS if out of buffer
3666 ** NFC_STATUS_BUSY if busy
3667 ** NFC_STATUS_FAILED if other error
3668 **
3669 *******************************************************************************/
RW_I93WriteDSFID(UINT8 dsfid)3670 tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
3671 {
3672 tNFC_STATUS status;
3673
3674 RW_TRACE_API0 ("RW_I93WriteDSFID ()");
3675
3676 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3677 {
3678 RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
3679 rw_cb.tcb.i93.state);
3680 return NFC_STATUS_BUSY;
3681 }
3682
3683 status = rw_i93_send_cmd_write_dsfid (dsfid);
3684 if (status == NFC_STATUS_OK)
3685 {
3686 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3687 }
3688
3689 return status;
3690 }
3691
3692 /*******************************************************************************
3693 **
3694 ** Function RW_I93LockDSFID
3695 **
3696 ** Description This function send Lock DSFID command
3697 **
3698 ** RW_I93_CMD_CMPL_EVT will be returned
3699 **
3700 ** Returns NFC_STATUS_OK if success
3701 ** NFC_STATUS_NO_BUFFERS if out of buffer
3702 ** NFC_STATUS_BUSY if busy
3703 ** NFC_STATUS_FAILED if other error
3704 **
3705 *******************************************************************************/
RW_I93LockDSFID(void)3706 tNFC_STATUS RW_I93LockDSFID (void)
3707 {
3708 tNFC_STATUS status;
3709
3710 RW_TRACE_API0 ("RW_I93LockDSFID ()");
3711
3712 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3713 {
3714 RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
3715 rw_cb.tcb.i93.state);
3716 return NFC_STATUS_BUSY;
3717 }
3718
3719 status = rw_i93_send_cmd_lock_dsfid ();
3720 if (status == NFC_STATUS_OK)
3721 {
3722 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3723 }
3724
3725 return status;
3726 }
3727
3728 /*******************************************************************************
3729 **
3730 ** Function RW_I93GetSysInfo
3731 **
3732 ** Description This function send Get System Information command
3733 **
3734 ** RW_I93_RESPONSE_EVT will be returned
3735 **
3736 ** Returns NFC_STATUS_OK if success
3737 ** NFC_STATUS_NO_BUFFERS if out of buffer
3738 ** NFC_STATUS_BUSY if busy
3739 ** NFC_STATUS_FAILED if other error
3740 **
3741 *******************************************************************************/
RW_I93GetSysInfo(UINT8 * p_uid)3742 tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
3743 {
3744 tNFC_STATUS status;
3745
3746 RW_TRACE_API0 ("RW_I93GetSysInfo ()");
3747
3748 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3749 {
3750 RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
3751 rw_cb.tcb.i93.state);
3752 return NFC_STATUS_BUSY;
3753 }
3754
3755 if (p_uid)
3756 {
3757 status = rw_i93_send_cmd_get_sys_info (p_uid, I93_FLAG_PROT_EXT_NO);
3758 }
3759 else
3760 {
3761 status = rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO);
3762 }
3763
3764 if (status == NFC_STATUS_OK)
3765 {
3766 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3767 }
3768
3769 return status;
3770 }
3771
3772 /*******************************************************************************
3773 **
3774 ** Function RW_I93GetMultiBlockSecurityStatus
3775 **
3776 ** Description This function send Get Multiple Block Security Status command
3777 **
3778 ** RW_I93_RESPONSE_EVT will be returned
3779 **
3780 ** Returns NFC_STATUS_OK if success
3781 ** NFC_STATUS_NO_BUFFERS if out of buffer
3782 ** NFC_STATUS_BUSY if busy
3783 ** NFC_STATUS_FAILED if other error
3784 **
3785 *******************************************************************************/
RW_I93GetMultiBlockSecurityStatus(UINT16 first_block_number,UINT16 number_blocks)3786 tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT16 first_block_number,
3787 UINT16 number_blocks)
3788 {
3789 tNFC_STATUS status;
3790
3791 RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
3792
3793 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3794 {
3795 RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
3796 rw_cb.tcb.i93.state);
3797 return NFC_STATUS_BUSY;
3798 }
3799
3800 status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
3801 if (status == NFC_STATUS_OK)
3802 {
3803 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3804 }
3805
3806 return status;
3807 }
3808
3809 /*******************************************************************************
3810 **
3811 ** Function RW_I93DetectNDef
3812 **
3813 ** Description This function performs NDEF detection procedure
3814 **
3815 ** RW_I93_NDEF_DETECT_EVT will be returned
3816 **
3817 ** Returns NFC_STATUS_OK if success
3818 ** NFC_STATUS_FAILED if busy or other error
3819 **
3820 *******************************************************************************/
RW_I93DetectNDef(void)3821 tNFC_STATUS RW_I93DetectNDef (void)
3822 {
3823 tNFC_STATUS status;
3824 tRW_I93_RW_SUBSTATE sub_state;
3825
3826 RW_TRACE_API0 ("RW_I93DetectNDef ()");
3827
3828 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3829 {
3830 RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
3831 rw_cb.tcb.i93.state);
3832 return NFC_STATUS_FAILED;
3833 }
3834
3835 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
3836 {
3837 status = rw_i93_send_cmd_inventory (NULL, FALSE, 0x00);
3838 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3839 }
3840 else if ( (rw_cb.tcb.i93.num_block == 0)
3841 ||(rw_cb.tcb.i93.block_size == 0) )
3842 {
3843 status = rw_i93_send_cmd_get_sys_info (rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3844 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
3845
3846 /* clear all flags */
3847 rw_cb.tcb.i93.intl_flags = 0;
3848 }
3849 else
3850 {
3851 /* read CC in the first block */
3852 status = rw_i93_send_cmd_read_single_block (0x0000, FALSE);
3853 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3854 }
3855
3856 if (status == NFC_STATUS_OK)
3857 {
3858 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3859 rw_cb.tcb.i93.sub_state = sub_state;
3860
3861 /* clear flags except flag for 2 bytes of number of blocks */
3862 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3863 }
3864
3865 return (status);
3866 }
3867
3868 /*******************************************************************************
3869 **
3870 ** Function RW_I93ReadNDef
3871 **
3872 ** Description This function performs NDEF read procedure
3873 ** Note: RW_I93DetectNDef () must be called before using this
3874 **
3875 ** The following event will be returned
3876 ** RW_I93_NDEF_READ_EVT for each segmented NDEF message
3877 ** RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
3878 ** RW_I93_NDEF_READ_FAIL_EVT for failure
3879 **
3880 ** Returns NFC_STATUS_OK if success
3881 ** NFC_STATUS_FAILED if I93 is busy or other error
3882 **
3883 *******************************************************************************/
RW_I93ReadNDef(void)3884 tNFC_STATUS RW_I93ReadNDef (void)
3885 {
3886 RW_TRACE_API0 ("RW_I93ReadNDef ()");
3887
3888 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3889 {
3890 RW_TRACE_ERROR1 ("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
3891 rw_cb.tcb.i93.state);
3892 return NFC_STATUS_FAILED;
3893 }
3894
3895 if ( (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3896 &&(rw_cb.tcb.i93.ndef_length > 0) )
3897 {
3898 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3899 rw_cb.tcb.i93.rw_length = 0;
3900
3901 if (rw_i93_get_next_blocks (rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK)
3902 {
3903 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3904 }
3905 else
3906 {
3907 return NFC_STATUS_FAILED;
3908 }
3909 }
3910 else
3911 {
3912 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3913 return NFC_STATUS_FAILED;
3914 }
3915
3916 return NFC_STATUS_OK;
3917 }
3918
3919 /*******************************************************************************
3920 **
3921 ** Function RW_I93UpdateNDef
3922 **
3923 ** Description This function performs NDEF update procedure
3924 ** Note: RW_I93DetectNDef () must be called before using this
3925 ** Updating data must not be removed until returning event
3926 **
3927 ** The following event will be returned
3928 ** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3929 ** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3930 **
3931 ** Returns NFC_STATUS_OK if success
3932 ** NFC_STATUS_FAILED if I93 is busy or other error
3933 **
3934 *******************************************************************************/
RW_I93UpdateNDef(UINT16 length,UINT8 * p_data)3935 tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data)
3936 {
3937 UINT16 block_number;
3938
3939 RW_TRACE_API1 ("RW_I93UpdateNDef () length:%d", length);
3940
3941 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3942 {
3943 RW_TRACE_ERROR1 ("RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
3944 rw_cb.tcb.i93.state);
3945 return NFC_STATUS_FAILED;
3946 }
3947
3948 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3949 {
3950 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
3951 {
3952 RW_TRACE_ERROR0 ("RW_I93UpdateNDef ():NDEF is read-only");
3953 return NFC_STATUS_FAILED;
3954 }
3955 if (rw_cb.tcb.i93.max_ndef_length < length)
3956 {
3957 RW_TRACE_ERROR2 ("RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length (%d)",
3958 length, rw_cb.tcb.i93.max_ndef_length);
3959 return NFC_STATUS_FAILED;
3960 }
3961
3962 rw_cb.tcb.i93.ndef_length = length;
3963 rw_cb.tcb.i93.p_update_data = p_data;
3964
3965 /* read length field */
3966 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3967 rw_cb.tcb.i93.rw_length = 0;
3968
3969 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
3970
3971 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
3972 {
3973 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3974 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3975 }
3976 else
3977 {
3978 return NFC_STATUS_FAILED;
3979 }
3980 }
3981 else
3982 {
3983 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3984 return NFC_STATUS_FAILED;
3985 }
3986
3987 return NFC_STATUS_OK;
3988 }
3989
3990 /*******************************************************************************
3991 **
3992 ** Function RW_I93FormatNDef
3993 **
3994 ** Description This function performs formatting procedure
3995 **
3996 ** RW_I93_FORMAT_CPLT_EVT will be returned
3997 **
3998 ** Returns NFC_STATUS_OK if success
3999 ** NFC_STATUS_FAILED if busy or other error
4000 **
4001 *******************************************************************************/
RW_I93FormatNDef(void)4002 tNFC_STATUS RW_I93FormatNDef (void)
4003 {
4004 tNFC_STATUS status;
4005 tRW_I93_RW_SUBSTATE sub_state;
4006
4007 RW_TRACE_API0 ("RW_I93FormatNDef ()");
4008
4009 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4010 {
4011 RW_TRACE_ERROR1 ("RW_I93FormatNDef ():Unable to start command at state (0x%X)",
4012 rw_cb.tcb.i93.state);
4013 return NFC_STATUS_FAILED;
4014 }
4015
4016 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
4017 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
4018 {
4019 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus */
4020 rw_cb.tcb.i93.rw_offset = 0;
4021
4022 /* read blocks with option flag to get block security status */
4023 status = rw_i93_send_cmd_read_single_block (0x0000, TRUE);
4024 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
4025 }
4026 else
4027 {
4028 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
4029 sub_state = RW_I93_SUBSTATE_WAIT_UID;
4030 }
4031
4032 if (status == NFC_STATUS_OK)
4033 {
4034 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
4035 rw_cb.tcb.i93.sub_state = sub_state;
4036 rw_cb.tcb.i93.intl_flags = 0;
4037 }
4038
4039 return (status);
4040 }
4041
4042 /*******************************************************************************
4043 **
4044 ** Function RW_I93SetTagReadOnly
4045 **
4046 ** Description This function performs NDEF read-only procedure
4047 ** Note: RW_I93DetectNDef () must be called before using this
4048 ** Updating data must not be removed until returning event
4049 **
4050 ** The RW_I93_SET_TAG_RO_EVT event will be returned.
4051 **
4052 ** Returns NFC_STATUS_OK if success
4053 ** NFC_STATUS_FAILED if I93 is busy or other error
4054 **
4055 *******************************************************************************/
RW_I93SetTagReadOnly(void)4056 tNFC_STATUS RW_I93SetTagReadOnly (void)
4057 {
4058 RW_TRACE_API0 ("RW_I93SetTagReadOnly ()");
4059
4060 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4061 {
4062 RW_TRACE_ERROR1 ("RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
4063 rw_cb.tcb.i93.state);
4064 return NFC_STATUS_FAILED;
4065 }
4066
4067 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
4068 {
4069 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
4070 {
4071 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():NDEF is already read-only");
4072 return NFC_STATUS_FAILED;
4073 }
4074
4075 /* get CC in the first block */
4076 if (rw_i93_send_cmd_read_single_block (0, FALSE) == NFC_STATUS_OK)
4077 {
4078 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4079 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
4080 }
4081 else
4082 {
4083 return NFC_STATUS_FAILED;
4084 }
4085 }
4086 else
4087 {
4088 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():No NDEF detected");
4089 return NFC_STATUS_FAILED;
4090 }
4091
4092 return NFC_STATUS_OK;
4093 }
4094
4095 /*****************************************************************************
4096 **
4097 ** Function RW_I93PresenceCheck
4098 **
4099 ** Description Check if the tag is still in the field.
4100 **
4101 ** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
4102 ** presence or non-presence.
4103 **
4104 ** Returns NFC_STATUS_OK, if raw data frame sent
4105 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
4106 ** NFC_STATUS_FAILED: other error
4107 **
4108 *****************************************************************************/
RW_I93PresenceCheck(void)4109 tNFC_STATUS RW_I93PresenceCheck (void)
4110 {
4111
4112 tNFC_STATUS status;
4113 tRW_DATA evt_data;
4114
4115 RW_TRACE_API0 ("RW_I93PresenceCheck ()");
4116
4117 if (!rw_cb.p_cback)
4118 {
4119 return NFC_STATUS_FAILED;
4120 }
4121 else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED)
4122 {
4123 evt_data.status = NFC_STATUS_FAILED;
4124 (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
4125
4126 return NFC_STATUS_OK;
4127 }
4128 else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4129 {
4130 return NFC_STATUS_BUSY;
4131 }
4132 else
4133 {
4134 /* The support of AFI by the VICC is optional, so do not include AFI */
4135 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
4136
4137 if (status == NFC_STATUS_OK)
4138 {
4139 /* do not retry during presence check */
4140 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
4141 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
4142 }
4143 }
4144
4145 return (status);
4146 }
4147
4148 #if (BT_TRACE_VERBOSE == TRUE)
4149 /*******************************************************************************
4150 **
4151 ** Function rw_i93_get_state_name
4152 **
4153 ** Description This function returns the state name.
4154 **
4155 ** NOTE conditionally compiled to save memory.
4156 **
4157 ** Returns pointer to the name
4158 **
4159 *******************************************************************************/
rw_i93_get_state_name(UINT8 state)4160 static char *rw_i93_get_state_name (UINT8 state)
4161 {
4162 switch (state)
4163 {
4164 case RW_I93_STATE_NOT_ACTIVATED:
4165 return ("NOT_ACTIVATED");
4166 case RW_I93_STATE_IDLE:
4167 return ("IDLE");
4168 case RW_I93_STATE_BUSY:
4169 return ("BUSY");
4170
4171 case RW_I93_STATE_DETECT_NDEF:
4172 return ("NDEF_DETECTION");
4173 case RW_I93_STATE_READ_NDEF:
4174 return ("READ_NDEF");
4175 case RW_I93_STATE_UPDATE_NDEF:
4176 return ("UPDATE_NDEF");
4177 case RW_I93_STATE_FORMAT:
4178 return ("FORMAT");
4179 case RW_I93_STATE_SET_READ_ONLY:
4180 return ("SET_READ_ONLY");
4181
4182 case RW_I93_STATE_PRESENCE_CHECK:
4183 return ("PRESENCE_CHECK");
4184 default:
4185 return ("???? UNKNOWN STATE");
4186 }
4187 }
4188
4189 /*******************************************************************************
4190 **
4191 ** Function rw_i93_get_sub_state_name
4192 **
4193 ** Description This function returns the sub_state name.
4194 **
4195 ** NOTE conditionally compiled to save memory.
4196 **
4197 ** Returns pointer to the name
4198 **
4199 *******************************************************************************/
rw_i93_get_sub_state_name(UINT8 sub_state)4200 static char *rw_i93_get_sub_state_name (UINT8 sub_state)
4201 {
4202 switch (sub_state)
4203 {
4204 case RW_I93_SUBSTATE_WAIT_UID:
4205 return ("WAIT_UID");
4206 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
4207 return ("WAIT_SYS_INFO");
4208 case RW_I93_SUBSTATE_WAIT_CC:
4209 return ("WAIT_CC");
4210 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
4211 return ("SEARCH_NDEF_TLV");
4212 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
4213 return ("CHECK_LOCK_STATUS");
4214 case RW_I93_SUBSTATE_RESET_LEN:
4215 return ("RESET_LEN");
4216 case RW_I93_SUBSTATE_WRITE_NDEF:
4217 return ("WRITE_NDEF");
4218 case RW_I93_SUBSTATE_UPDATE_LEN:
4219 return ("UPDATE_LEN");
4220 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
4221 return ("WAIT_RESET_DSFID_AFI");
4222 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
4223 return ("CHECK_READ_ONLY");
4224 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
4225 return ("WRITE_CC_NDEF_TLV");
4226 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
4227 return ("WAIT_UPDATE_CC");
4228 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
4229 return ("LOCK_NDEF_TLV");
4230 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
4231 return ("WAIT_LOCK_CC");
4232 default:
4233 return ("???? UNKNOWN SUBSTATE");
4234 }
4235 }
4236
4237 /*******************************************************************************
4238 **
4239 ** Function rw_i93_get_tag_name
4240 **
4241 ** Description This function returns the tag name.
4242 **
4243 ** NOTE conditionally compiled to save memory.
4244 **
4245 ** Returns pointer to the name
4246 **
4247 *******************************************************************************/
rw_i93_get_tag_name(UINT8 product_version)4248 static char *rw_i93_get_tag_name (UINT8 product_version)
4249 {
4250 switch (product_version)
4251 {
4252 case RW_I93_ICODE_SLI:
4253 return ("SLI/SLIX");
4254 case RW_I93_ICODE_SLI_S:
4255 return ("SLI-S/SLIX-S");
4256 case RW_I93_ICODE_SLI_L:
4257 return ("SLI-L/SLIX-L");
4258 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
4259 return ("Tag-it HF-I Plus Inlay");
4260 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
4261 return ("Tag-it HF-I Plus Chip");
4262 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
4263 return ("Tag-it HF-I Standard Chip/Inlyas");
4264 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
4265 return ("Tag-it HF-I Pro Chip/Inlays");
4266 case RW_I93_STM_LRI1K:
4267 return ("LRi1K");
4268 case RW_I93_STM_LRI2K:
4269 return ("LRi2K");
4270 case RW_I93_STM_LRIS2K:
4271 return ("LRiS2K");
4272 case RW_I93_STM_LRIS64K:
4273 return ("LRiS64K");
4274 case RW_I93_STM_M24LR64_R:
4275 return ("M24LR64");
4276 case RW_I93_STM_M24LR04E_R:
4277 return ("M24LR04E");
4278 case RW_I93_STM_M24LR16E_R:
4279 return ("M24LR16E");
4280 case RW_I93_STM_M24LR64E_R:
4281 return ("M24LR64E");
4282 case RW_I93_UNKNOWN_PRODUCT:
4283 default:
4284 return ("UNKNOWN");
4285 }
4286 }
4287
4288 #endif
4289
4290 #endif /* (NFC_INCLUDED == TRUE) */
4291