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