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 else
2001 {
2002 /* in case of no Ndef data included */
2003 p_resp->len = 0;
2004 }
2005
2006 /* if read all of NDEF data */
2007 if (p_i93->rw_length >= p_i93->ndef_length)
2008 {
2009 /* remove extra btyes in the last block */
2010 p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
2011
2012 p_i93->state = RW_I93_STATE_IDLE;
2013 p_i93->sent_cmd = 0;
2014
2015 RW_TRACE_DEBUG2 ("NDEF read complete read (%d)/total (%d)",
2016 p_resp->len,
2017 p_i93->ndef_length);
2018
2019 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
2020 }
2021 else
2022 {
2023 RW_TRACE_DEBUG2 ("NDEF read segment read (%d)/total (%d)",
2024 p_resp->len,
2025 p_i93->ndef_length);
2026
2027 if (p_resp->len > 0)
2028 {
2029 (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_EVT, &rw_data);
2030 }
2031
2032 /* this will make read data from next block */
2033 p_i93->rw_offset += length;
2034
2035 if (rw_i93_get_next_blocks (p_i93->rw_offset) != NFC_STATUS_OK)
2036 {
2037 rw_i93_handle_error (NFC_STATUS_FAILED);
2038 }
2039 }
2040 }
2041
2042 /*******************************************************************************
2043 **
2044 ** Function rw_i93_sm_update_ndef
2045 **
2046 ** Description Process NDEF update procedure
2047 **
2048 ** 1. Set length field to zero
2049 ** 2. Write NDEF and Terminator TLV
2050 ** 3. Set length field to NDEF length
2051 **
2052 ** Returns void
2053 **
2054 *******************************************************************************/
rw_i93_sm_update_ndef(BT_HDR * p_resp)2055 void rw_i93_sm_update_ndef (BT_HDR *p_resp)
2056 {
2057 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
2058 UINT8 flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
2059 UINT16 length = p_resp->len, block_number;
2060 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2061 tRW_DATA rw_data;
2062
2063 #if (BT_TRACE_VERBOSE == TRUE)
2064 RW_TRACE_DEBUG2 ("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
2065 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2066 #else
2067 RW_TRACE_DEBUG1 ("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
2068 #endif
2069
2070 STREAM_TO_UINT8 (flags, p);
2071 length--;
2072
2073 if (flags & I93_FLAG_ERROR_DETECTED)
2074 {
2075 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2076 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2077 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2078 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2079 &&
2080 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2081 {
2082 /* ignore error */
2083 }
2084 else
2085 {
2086 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2087 rw_i93_handle_error (NFC_STATUS_FAILED);
2088 return;
2089 }
2090 }
2091
2092 switch (p_i93->sub_state)
2093 {
2094 case RW_I93_SUBSTATE_RESET_LEN:
2095
2096 /* get offset of length field */
2097 length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
2098
2099 /* set length to zero */
2100 *(p + length_offset) = 0x00;
2101
2102 if (p_i93->ndef_length > 0)
2103 {
2104 /* if 3 bytes length field is needed */
2105 if (p_i93->ndef_length >= 0xFF)
2106 {
2107 xx = length_offset + 3;
2108 }
2109 else
2110 {
2111 xx = length_offset + 1;
2112 }
2113
2114 /* write the first part of NDEF in the same block */
2115 for ( ; xx < p_i93->block_size; xx++)
2116 {
2117 if (p_i93->rw_length < p_i93->ndef_length)
2118 {
2119 *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
2120 }
2121 else
2122 {
2123 *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
2124 }
2125 }
2126 }
2127
2128 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2129
2130 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2131 {
2132 /* update next writing offset */
2133 p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
2134 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
2135 }
2136 else
2137 {
2138 rw_i93_handle_error (NFC_STATUS_FAILED);
2139 }
2140 break;
2141
2142 case RW_I93_SUBSTATE_WRITE_NDEF:
2143
2144 /* if it's not the end of tag memory */
2145 if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block)
2146 {
2147 block_number = p_i93->rw_offset / p_i93->block_size;
2148
2149 /* if we have more data to write */
2150 if (p_i93->rw_length < p_i93->ndef_length)
2151 {
2152 p = p_i93->p_update_data + p_i93->rw_length;
2153
2154 p_i93->rw_offset += p_i93->block_size;
2155 p_i93->rw_length += p_i93->block_size;
2156
2157 /* if this is the last block of NDEF TLV */
2158 if (p_i93->rw_length > p_i93->ndef_length)
2159 {
2160 /* length of NDEF TLV in the block */
2161 xx = (UINT8) (p_i93->block_size - (p_i93->rw_length - p_i93->ndef_length));
2162
2163 /* set NULL TLV in the unused part of block */
2164 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2165 memcpy (buff, p, xx);
2166 p = buff;
2167
2168 /* if it's the end of tag memory */
2169 if ( (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
2170 &&(xx < p_i93->block_size) )
2171 {
2172 buff[xx] = I93_ICODE_TLV_TYPE_TERM;
2173 }
2174
2175 p_i93->ndef_tlv_last_offset = p_i93->rw_offset - p_i93->block_size + xx - 1;
2176 }
2177
2178 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2179 {
2180 rw_i93_handle_error (NFC_STATUS_FAILED);
2181 }
2182 }
2183 else
2184 {
2185 /* if this is the very next block of NDEF TLV */
2186 if (block_number == (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1)
2187 {
2188 p_i93->rw_offset += p_i93->block_size;
2189
2190 /* write Terminator TLV and NULL TLV */
2191 memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
2192 buff[0] = I93_ICODE_TLV_TYPE_TERM;
2193 p = buff;
2194
2195 if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
2196 {
2197 rw_i93_handle_error (NFC_STATUS_FAILED);
2198 }
2199 }
2200 else
2201 {
2202 /* finished writing NDEF and Terminator TLV */
2203 /* read length field to update length */
2204 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2205
2206 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2207 {
2208 /* set offset to length field */
2209 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2210
2211 /* get size of length field */
2212 if (p_i93->ndef_length >= 0xFF)
2213 {
2214 p_i93->rw_length = 3;
2215 }
2216 else if (p_i93->ndef_length > 0)
2217 {
2218 p_i93->rw_length = 1;
2219 }
2220 else
2221 {
2222 p_i93->rw_length = 0;
2223 }
2224
2225 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2226 }
2227 else
2228 {
2229 rw_i93_handle_error (NFC_STATUS_FAILED);
2230 }
2231 }
2232 }
2233 }
2234 else
2235 {
2236 /* if we have no more data to write */
2237 if (p_i93->rw_length >= p_i93->ndef_length)
2238 {
2239 /* finished writing NDEF and Terminator TLV */
2240 /* read length field to update length */
2241 block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
2242
2243 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
2244 {
2245 /* set offset to length field */
2246 p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
2247
2248 /* get size of length field */
2249 if (p_i93->ndef_length >= 0xFF)
2250 {
2251 p_i93->rw_length = 3;
2252 }
2253 else if (p_i93->ndef_length > 0)
2254 {
2255 p_i93->rw_length = 1;
2256 }
2257 else
2258 {
2259 p_i93->rw_length = 0;
2260 }
2261
2262 p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
2263 break;
2264 }
2265 }
2266 rw_i93_handle_error (NFC_STATUS_FAILED);
2267 }
2268 break;
2269
2270 case RW_I93_SUBSTATE_UPDATE_LEN:
2271
2272 /* if we have more length field to write */
2273 if (p_i93->rw_length > 0)
2274 {
2275 /* if we got ack for writing, read next block to update rest of length field */
2276 if (length == 0)
2277 {
2278 block_number = p_i93->rw_offset / p_i93->block_size;
2279
2280 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) != NFC_STATUS_OK)
2281 {
2282 rw_i93_handle_error (NFC_STATUS_FAILED);
2283 }
2284 }
2285 else
2286 {
2287 length_offset = p_i93->rw_offset % p_i93->block_size;
2288
2289 /* update length field within the read block */
2290 for (xx = length_offset; xx < p_i93->block_size; xx++)
2291 {
2292 if (p_i93->rw_length == 3)
2293 *(p + xx) = 0xFF;
2294 else if (p_i93->rw_length == 2)
2295 *(p + xx) = (UINT8) ((p_i93->ndef_length >> 8) & 0xFF);
2296 else if (p_i93->rw_length == 1)
2297 *(p + xx) = (UINT8) (p_i93->ndef_length & 0xFF);
2298
2299 p_i93->rw_length--;
2300 if (p_i93->rw_length == 0)
2301 break;
2302 }
2303
2304 block_number = (p_i93->rw_offset / p_i93->block_size);
2305
2306 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2307 {
2308 /* set offset to the beginning of next block */
2309 p_i93->rw_offset += p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
2310 }
2311 else
2312 {
2313 rw_i93_handle_error (NFC_STATUS_FAILED);
2314 }
2315 }
2316 }
2317 else
2318 {
2319 RW_TRACE_DEBUG3 ("NDEF update complete, %d bytes, (%d-%d)",
2320 p_i93->ndef_length,
2321 p_i93->ndef_tlv_start_offset,
2322 p_i93->ndef_tlv_last_offset);
2323
2324 p_i93->state = RW_I93_STATE_IDLE;
2325 p_i93->sent_cmd = 0;
2326 p_i93->p_update_data = NULL;
2327
2328 rw_data.status = NFC_STATUS_OK;
2329 (*(rw_cb.p_cback)) (RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
2330 }
2331 break;
2332
2333 default:
2334 break;
2335 }
2336 }
2337
2338 /*******************************************************************************
2339 **
2340 ** Function rw_i93_sm_format
2341 **
2342 ** Description Process format procedure
2343 **
2344 ** 1. Get UID
2345 ** 2. Get sys info for memory size (reset AFI/DSFID)
2346 ** 3. Get block status to get read-only status
2347 ** 4. Write CC and empty NDEF
2348 **
2349 ** Returns void
2350 **
2351 *******************************************************************************/
rw_i93_sm_format(BT_HDR * p_resp)2352 void rw_i93_sm_format (BT_HDR *p_resp)
2353 {
2354 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
2355 UINT8 flags;
2356 UINT16 length = p_resp->len, xx, block_number;
2357 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2358 tRW_DATA rw_data;
2359 tNFC_STATUS status = NFC_STATUS_FAILED;
2360
2361 #if (BT_TRACE_VERBOSE == TRUE)
2362 RW_TRACE_DEBUG2 ("rw_i93_sm_format () sub_state:%s (0x%x)",
2363 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2364 #else
2365 RW_TRACE_DEBUG1 ("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
2366 #endif
2367
2368 STREAM_TO_UINT8 (flags, p);
2369 length--;
2370
2371 if (flags & I93_FLAG_ERROR_DETECTED)
2372 {
2373 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2374 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2375 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2376 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2377 &&
2378 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2379 {
2380 /* ignore error */
2381 }
2382 else if ((length) && (rw_i93_check_sys_info_prot_ext(*p)))
2383 {
2384 /* getting system info with protocol extension flag */
2385 /* This STM tag supports more than 2040 bytes */
2386 p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
2387 return;
2388 }
2389 else
2390 {
2391 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2392 rw_i93_handle_error (NFC_STATUS_FAILED);
2393 return;
2394 }
2395 }
2396
2397 switch (p_i93->sub_state)
2398 {
2399 case RW_I93_SUBSTATE_WAIT_UID:
2400
2401 p++; /* skip DSFID */
2402 p_uid = p_i93->uid;
2403 STREAM_TO_ARRAY8 (p_uid, p); /* store UID */
2404
2405 /* get system information to get memory size */
2406 if (rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO) == NFC_STATUS_OK)
2407 {
2408 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
2409 }
2410 else
2411 {
2412 rw_i93_handle_error (NFC_STATUS_FAILED);
2413 }
2414 break;
2415
2416 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
2417
2418 p_i93->block_size = 0;
2419 p_i93->num_block = 0;
2420
2421 if (!rw_i93_process_sys_info (p))
2422 {
2423 /* retrying with protocol extension flag */
2424 break;
2425 }
2426
2427 if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
2428 {
2429 /* DSFID, if any DSFID then reset */
2430 if (p_i93->dsfid != I93_DFS_UNSUPPORTED)
2431 {
2432 p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
2433 }
2434 }
2435 if (p_i93->info_flags & I93_INFO_FLAG_AFI)
2436 {
2437 /* AFI, reset to 0 */
2438 if (p_i93->afi != 0x00)
2439 {
2440 p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
2441 }
2442 }
2443
2444 if ((p_i93->block_size == 0)||(p_i93->num_block == 0))
2445 {
2446 RW_TRACE_DEBUG0 ("Unable to get tag memory size");
2447 rw_i93_handle_error (status);
2448 }
2449 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2450 {
2451 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
2452 {
2453 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2454 }
2455 else
2456 {
2457 rw_i93_handle_error (NFC_STATUS_FAILED);
2458 }
2459 }
2460 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2461 {
2462 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2463 {
2464 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2465 }
2466 else
2467 {
2468 rw_i93_handle_error (NFC_STATUS_FAILED);
2469 }
2470 }
2471 else
2472 {
2473 /* get lock status to see if read-only */
2474 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2475 {
2476 /* these doesn't support GetMultiBlockSecurityStatus */
2477
2478 rw_cb.tcb.i93.rw_offset = 0;
2479
2480 /* read blocks with option flag to get block security status */
2481 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
2482 {
2483 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2484 }
2485 else
2486 {
2487 rw_i93_handle_error (NFC_STATUS_FAILED);
2488 }
2489 }
2490 else
2491 {
2492 /* block offset for read-only check */
2493 p_i93->rw_offset = 0;
2494
2495 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2496 {
2497 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2498 }
2499 else
2500 {
2501 rw_i93_handle_error (NFC_STATUS_FAILED);
2502 }
2503 }
2504 }
2505
2506 break;
2507
2508 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
2509
2510 if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID)
2511 {
2512 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
2513 }
2514 else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI)
2515 {
2516 p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
2517 }
2518
2519 if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
2520 {
2521 if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
2522 {
2523 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2524 }
2525 else
2526 {
2527 rw_i93_handle_error (NFC_STATUS_FAILED);
2528 }
2529 }
2530 else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
2531 {
2532 if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
2533 {
2534 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
2535 }
2536 else
2537 {
2538 rw_i93_handle_error (NFC_STATUS_FAILED);
2539 }
2540 }
2541 else
2542 {
2543 /* get lock status to see if read-only */
2544 if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
2545 {
2546 /* these doesn't support GetMultiBlockSecurityStatus */
2547
2548 rw_cb.tcb.i93.rw_offset = 0;
2549
2550 /* read blocks with option flag to get block security status */
2551 if (rw_i93_send_cmd_read_single_block (0x0000, TRUE) == NFC_STATUS_OK)
2552 {
2553 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2554 }
2555 else
2556 {
2557 rw_i93_handle_error (NFC_STATUS_FAILED);
2558 }
2559 }
2560 else
2561 {
2562 /* block offset for read-only check */
2563 p_i93->rw_offset = 0;
2564
2565 if (rw_i93_get_next_block_sec () == NFC_STATUS_OK)
2566 {
2567 p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
2568 }
2569 else
2570 {
2571 rw_i93_handle_error (NFC_STATUS_FAILED);
2572 }
2573 }
2574 }
2575 break;
2576
2577 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
2578
2579 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2580 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
2581 ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) )
2582 {
2583 if ((*p) & I93_BLOCK_LOCKED)
2584 {
2585 rw_i93_handle_error (NFC_STATUS_FAILED);
2586 break;
2587 }
2588
2589 /* if we checked all of user blocks */
2590 if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block)
2591 {
2592 if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2593 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2594 {
2595 /* read the block which has AFI */
2596 p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2597 rw_i93_send_cmd_read_single_block ((UINT16)(p_i93->rw_offset/p_i93->block_size), TRUE);
2598 break;
2599 }
2600 }
2601 else if (p_i93->rw_offset == I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION)
2602 {
2603 /* no block is locked */
2604 }
2605 else
2606 {
2607 p_i93->rw_offset += p_i93->block_size;
2608 rw_i93_send_cmd_read_single_block ((UINT16)(p_i93->rw_offset/p_i93->block_size), TRUE);
2609 break;
2610 }
2611 }
2612 else
2613 {
2614 /* if any block is locked, we cannot format it */
2615 for (xx = 0; xx < length; xx++)
2616 {
2617 if (*(p + xx) & I93_BLOCK_LOCKED)
2618 {
2619 rw_i93_handle_error (NFC_STATUS_FAILED);
2620 break;
2621 }
2622 }
2623
2624 /* update block offset for read-only check */
2625 p_i93->rw_offset += length;
2626
2627 /* if need to get more lock status of blocks */
2628 if (p_i93->num_block > p_i93->rw_offset)
2629 {
2630 if (rw_i93_get_next_block_sec () != NFC_STATUS_OK)
2631 {
2632 rw_i93_handle_error (NFC_STATUS_FAILED);
2633 }
2634 break;
2635 }
2636 }
2637
2638 /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
2639 p_i93->p_update_data = (UINT8*) GKI_getbuf (RW_I93_FORMAT_DATA_LEN);
2640
2641 if (!p_i93->p_update_data)
2642 {
2643 RW_TRACE_ERROR0 ("rw_i93_sm_format (): Cannot allocate buffer");
2644 rw_i93_handle_error (NFC_STATUS_FAILED);
2645 break;
2646 }
2647
2648 p = p_i93->p_update_data;
2649
2650 /* Capability Container */
2651 *(p++) = I93_ICODE_CC_MAGIC_NUMER; /* magic number */
2652 *(p++) = 0x40; /* version 1.0, read/write */
2653
2654 /* if memory size is less than 2048 bytes */
2655 if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
2656 *(p++) = (UINT8) ((p_i93->num_block * p_i93->block_size) / 8); /* memory size */
2657 else
2658 *(p++) = 0xFF;
2659
2660 if ( (p_i93->product_version == RW_I93_ICODE_SLI)
2661 ||(p_i93->product_version == RW_I93_ICODE_SLI_S)
2662 ||(p_i93->product_version == RW_I93_ICODE_SLI_L) )
2663 {
2664 if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
2665 *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
2666 else
2667 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2668 }
2669 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2670 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) )
2671 {
2672 *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command supported */
2673 }
2674 else if ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2675 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2676 {
2677 *(p++) = 0;
2678 }
2679 else
2680 {
2681 /* STM except LRIS2K, Broadcom supports read multi block command */
2682
2683 /* if memory size is more than 2040 bytes (which is not LRIS2K) */
2684 if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
2685 *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
2686 else if (p_i93->product_version == RW_I93_STM_LRIS2K)
2687 *(p++) = 0x00;
2688 else
2689 *(p++) = I93_ICODE_CC_MBREAD_MASK;
2690 }
2691
2692 /* zero length NDEF and Terminator TLV */
2693 *(p++) = I93_ICODE_TLV_TYPE_NDEF;
2694 *(p++) = 0x00;
2695 *(p++) = I93_ICODE_TLV_TYPE_TERM;
2696 *(p++) = I93_ICODE_TLV_TYPE_NULL;
2697
2698 /* start from block 0 */
2699 p_i93->rw_offset = 0;
2700
2701 if (rw_i93_send_cmd_write_single_block (0, p_i93->p_update_data) == NFC_STATUS_OK)
2702 {
2703 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2704 p_i93->rw_offset += p_i93->block_size;
2705 }
2706 else
2707 {
2708 rw_i93_handle_error (NFC_STATUS_FAILED);
2709 }
2710 break;
2711
2712 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
2713
2714 /* if we have more data to write */
2715 if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN)
2716 {
2717 block_number = (p_i93->rw_offset / p_i93->block_size);
2718 p = p_i93->p_update_data + p_i93->rw_offset;
2719
2720 if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
2721 {
2722 p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
2723 p_i93->rw_offset += p_i93->block_size;
2724 }
2725 else
2726 {
2727 rw_i93_handle_error (NFC_STATUS_FAILED);
2728 }
2729 }
2730 else
2731 {
2732 GKI_freebuf (p_i93->p_update_data);
2733 p_i93->p_update_data = NULL;
2734
2735 p_i93->state = RW_I93_STATE_IDLE;
2736 p_i93->sent_cmd = 0;
2737
2738 rw_data.status = NFC_STATUS_OK;
2739 (*(rw_cb.p_cback)) (RW_I93_FORMAT_CPLT_EVT, &rw_data);
2740 }
2741 break;
2742
2743 default:
2744 break;
2745 }
2746 }
2747
2748 /*******************************************************************************
2749 **
2750 ** Function rw_i93_sm_set_read_only
2751 **
2752 ** Description Process read-only procedure
2753 **
2754 ** 1. Update CC as read-only
2755 ** 2. Lock all block of NDEF TLV
2756 ** 3. Lock block of CC
2757 **
2758 ** Returns void
2759 **
2760 *******************************************************************************/
rw_i93_sm_set_read_only(BT_HDR * p_resp)2761 void rw_i93_sm_set_read_only (BT_HDR *p_resp)
2762 {
2763 UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
2764 UINT8 flags, block_number;
2765 UINT16 length = p_resp->len;
2766 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2767 tRW_DATA rw_data;
2768
2769 #if (BT_TRACE_VERBOSE == TRUE)
2770 RW_TRACE_DEBUG2 ("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
2771 rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
2772 #else
2773 RW_TRACE_DEBUG1 ("rw_i93_sm_set_read_only () sub_state:0x%x", p_i93->sub_state);
2774 #endif
2775
2776 STREAM_TO_UINT8 (flags, p);
2777 length--;
2778
2779 if (flags & I93_FLAG_ERROR_DETECTED)
2780 {
2781 if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
2782 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
2783 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
2784 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
2785 &&
2786 (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
2787 {
2788 /* ignore error */
2789 }
2790 else
2791 {
2792 RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
2793 rw_i93_handle_error (NFC_STATUS_FAILED);
2794 return;
2795 }
2796 }
2797
2798 switch (p_i93->sub_state)
2799 {
2800 case RW_I93_SUBSTATE_WAIT_CC:
2801
2802 /* mark CC as read-only */
2803 *(p+1) |= I93_ICODE_CC_READ_ONLY;
2804
2805 if (rw_i93_send_cmd_write_single_block (0, p) == NFC_STATUS_OK)
2806 {
2807 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
2808 }
2809 else
2810 {
2811 rw_i93_handle_error (NFC_STATUS_FAILED);
2812 }
2813 break;
2814
2815 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
2816
2817 /* successfully write CC then lock all blocks of NDEF TLV */
2818 p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
2819 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2820
2821 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2822 {
2823 p_i93->rw_offset += p_i93->block_size;
2824 p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
2825 }
2826 else
2827 {
2828 rw_i93_handle_error (NFC_STATUS_FAILED);
2829 }
2830 break;
2831
2832 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
2833
2834 /* if we need to lock more blocks */
2835 if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset)
2836 {
2837 /* get the next block of NDEF TLV */
2838 block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
2839
2840 if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
2841 {
2842 p_i93->rw_offset += p_i93->block_size;
2843 }
2844 else
2845 {
2846 rw_i93_handle_error (NFC_STATUS_FAILED);
2847 }
2848 }
2849 /* if the first block of NDEF TLV is different from block of CC */
2850 else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0)
2851 {
2852 /* lock block of CC */
2853 if (rw_i93_send_cmd_lock_block (0) == NFC_STATUS_OK)
2854 {
2855 p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
2856 }
2857 else
2858 {
2859 rw_i93_handle_error (NFC_STATUS_FAILED);
2860 }
2861 }
2862 else
2863 {
2864 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2865 p_i93->state = RW_I93_STATE_IDLE;
2866 p_i93->sent_cmd = 0;
2867
2868 rw_data.status = NFC_STATUS_OK;
2869 (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
2870 }
2871 break;
2872
2873 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
2874
2875 p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
2876 p_i93->state = RW_I93_STATE_IDLE;
2877 p_i93->sent_cmd = 0;
2878
2879 rw_data.status = NFC_STATUS_OK;
2880 (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
2881 break;
2882
2883 default:
2884 break;
2885 }
2886 }
2887
2888 /*******************************************************************************
2889 **
2890 ** Function rw_i93_handle_error
2891 **
2892 ** Description notify error to application and clean up
2893 **
2894 ** Returns none
2895 **
2896 *******************************************************************************/
rw_i93_handle_error(tNFC_STATUS status)2897 void rw_i93_handle_error (tNFC_STATUS status)
2898 {
2899 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
2900 tRW_DATA rw_data;
2901 tRW_EVENT event;
2902
2903 RW_TRACE_DEBUG2 ("rw_i93_handle_error (): status:0x%02X, state:0x%X",
2904 status, p_i93->state);
2905
2906 nfc_stop_quick_timer (&p_i93->timer);
2907
2908 if (rw_cb.p_cback)
2909 {
2910 rw_data.status = status;
2911
2912 switch (p_i93->state)
2913 {
2914 case RW_I93_STATE_IDLE: /* in case of RawFrame */
2915 event = RW_I93_INTF_ERROR_EVT;
2916 break;
2917
2918 case RW_I93_STATE_BUSY:
2919 if (p_i93->sent_cmd == I93_CMD_STAY_QUIET)
2920 {
2921 /* There is no response to Stay Quiet command */
2922 rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
2923 rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
2924 rw_data.i93_cmd_cmpl.error_code = 0;
2925 event = RW_I93_CMD_CMPL_EVT;
2926 }
2927 else
2928 {
2929 event = RW_I93_INTF_ERROR_EVT;
2930 }
2931 break;
2932
2933 case RW_I93_STATE_DETECT_NDEF:
2934 rw_data.ndef.protocol = NFC_PROTOCOL_15693;
2935 rw_data.ndef.cur_size = 0;
2936 rw_data.ndef.max_size = 0;
2937 rw_data.ndef.flags = 0;
2938 rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
2939 rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
2940 event = RW_I93_NDEF_DETECT_EVT;
2941 break;
2942
2943 case RW_I93_STATE_READ_NDEF:
2944 event = RW_I93_NDEF_READ_FAIL_EVT;
2945 break;
2946
2947 case RW_I93_STATE_UPDATE_NDEF:
2948 p_i93->p_update_data = NULL;
2949 event = RW_I93_NDEF_UPDATE_FAIL_EVT;
2950 break;
2951
2952 case RW_I93_STATE_FORMAT:
2953 if (p_i93->p_update_data)
2954 {
2955 GKI_freebuf (p_i93->p_update_data);
2956 p_i93->p_update_data = NULL;
2957 }
2958 event = RW_I93_FORMAT_CPLT_EVT;
2959 break;
2960
2961 case RW_I93_STATE_SET_READ_ONLY:
2962 event = RW_I93_SET_TAG_RO_EVT;
2963 break;
2964
2965 case RW_I93_STATE_PRESENCE_CHECK:
2966 event = RW_I93_PRESENCE_CHECK_EVT;
2967 break;
2968
2969 default:
2970 event = RW_I93_MAX_EVT;
2971 break;
2972 }
2973
2974 p_i93->state = RW_I93_STATE_IDLE;
2975 p_i93->sent_cmd = 0;
2976
2977 if (event != RW_I93_MAX_EVT)
2978 {
2979 (*(rw_cb.p_cback)) (event, &rw_data);
2980 }
2981 }
2982 else
2983 {
2984 p_i93->state = RW_I93_STATE_IDLE;
2985 }
2986 }
2987
2988 /*******************************************************************************
2989 **
2990 ** Function rw_i93_process_timeout
2991 **
2992 ** Description process timeout event
2993 **
2994 ** Returns none
2995 **
2996 *******************************************************************************/
rw_i93_process_timeout(TIMER_LIST_ENT * p_tle)2997 void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle)
2998 {
2999 BT_HDR *p_buf;
3000
3001 RW_TRACE_DEBUG1 ("rw_i93_process_timeout () event=%d", p_tle->event);
3002
3003 if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE)
3004 {
3005 if ( (rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES)
3006 &&(rw_cb.tcb.i93.p_retry_cmd)
3007 &&(rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET))
3008 {
3009 rw_cb.tcb.i93.retry_count++;
3010 RW_TRACE_ERROR1 ("rw_i93_process_timeout (): retry_count = %d", rw_cb.tcb.i93.retry_count);
3011
3012 p_buf = rw_cb.tcb.i93.p_retry_cmd;
3013 rw_cb.tcb.i93.p_retry_cmd = NULL;
3014
3015 if (rw_i93_send_to_lower (p_buf))
3016 {
3017 return;
3018 }
3019 }
3020
3021 /* all retrial is done or failed to send command to lower layer */
3022 if (rw_cb.tcb.i93.p_retry_cmd)
3023 {
3024 GKI_freebuf (rw_cb.tcb.i93.p_retry_cmd);
3025 rw_cb.tcb.i93.p_retry_cmd = NULL;
3026 rw_cb.tcb.i93.retry_count = 0;
3027 }
3028 rw_i93_handle_error (NFC_STATUS_TIMEOUT);
3029 }
3030 else
3031 {
3032 RW_TRACE_ERROR1 ("rw_i93_process_timeout () unknown event=%d", p_tle->event);
3033 }
3034 }
3035
3036 /*******************************************************************************
3037 **
3038 ** Function rw_i93_data_cback
3039 **
3040 ** Description This callback function receives the data from NFCC.
3041 **
3042 ** Returns none
3043 **
3044 *******************************************************************************/
rw_i93_data_cback(UINT8 conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)3045 static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
3046 {
3047 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
3048 BT_HDR *p_resp;
3049 tRW_DATA rw_data;
3050
3051 #if (BT_TRACE_VERBOSE == TRUE)
3052 UINT8 begin_state = p_i93->state;
3053 #endif
3054
3055 RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
3056
3057 if ( (event == NFC_DEACTIVATE_CEVT)
3058 ||(event == NFC_ERROR_CEVT) )
3059 {
3060 nfc_stop_quick_timer (&p_i93->timer);
3061
3062 if (event == NFC_ERROR_CEVT)
3063 {
3064 if ( (p_i93->retry_count < RW_MAX_RETRIES)
3065 &&(p_i93->p_retry_cmd) )
3066 {
3067 p_i93->retry_count++;
3068
3069 RW_TRACE_ERROR1 ("rw_i93_data_cback (): retry_count = %d", p_i93->retry_count);
3070
3071 p_resp = p_i93->p_retry_cmd;
3072 p_i93->p_retry_cmd = NULL;
3073 if (rw_i93_send_to_lower (p_resp))
3074 {
3075 return;
3076 }
3077 }
3078
3079 /* all retrial is done or failed to send command to lower layer */
3080 if (p_i93->p_retry_cmd)
3081 {
3082 GKI_freebuf (p_i93->p_retry_cmd);
3083 p_i93->p_retry_cmd = NULL;
3084 p_i93->retry_count = 0;
3085 }
3086
3087 rw_i93_handle_error ((tNFC_STATUS) (*(UINT8*) p_data));
3088 }
3089 else
3090 {
3091 /* free retry buffer */
3092 if (p_i93->p_retry_cmd)
3093 {
3094 GKI_freebuf (p_i93->p_retry_cmd);
3095 p_i93->p_retry_cmd = NULL;
3096 p_i93->retry_count = 0;
3097 }
3098 NFC_SetStaticRfCback (NULL);
3099 p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
3100 }
3101 return;
3102 }
3103
3104 if (event != NFC_DATA_CEVT)
3105 {
3106 return;
3107 }
3108
3109 p_resp = (BT_HDR *) p_data->data.p_data;
3110
3111 nfc_stop_quick_timer (&p_i93->timer);
3112
3113 /* free retry buffer */
3114 if (p_i93->p_retry_cmd)
3115 {
3116 GKI_freebuf (p_i93->p_retry_cmd);
3117 p_i93->p_retry_cmd = NULL;
3118 p_i93->retry_count = 0;
3119 }
3120
3121 #if (BT_TRACE_PROTOCOL == TRUE)
3122 DispRWI93Tag (p_resp, TRUE, p_i93->sent_cmd);
3123 #endif
3124
3125 #if (BT_TRACE_VERBOSE == TRUE)
3126 RW_TRACE_DEBUG2 ("RW I93 state: <%s (%d)>",
3127 rw_i93_get_state_name (p_i93->state), p_i93->state);
3128 #else
3129 RW_TRACE_DEBUG1 ("RW I93 state: %d", p_i93->state);
3130 #endif
3131
3132 switch (p_i93->state)
3133 {
3134 case RW_I93_STATE_IDLE:
3135 /* Unexpected Response from VICC, it should be raw frame response */
3136 /* forward to upper layer without parsing */
3137 p_i93->sent_cmd = 0;
3138 if (rw_cb.p_cback)
3139 {
3140 rw_data.raw_frame.status = p_data->data.status;
3141 rw_data.raw_frame.p_data = p_resp;
3142 (*(rw_cb.p_cback)) (RW_I93_RAW_FRAME_EVT, &rw_data);
3143 p_resp = NULL;
3144 }
3145 else
3146 {
3147 GKI_freebuf (p_resp);
3148 }
3149 break;
3150 case RW_I93_STATE_BUSY:
3151 p_i93->state = RW_I93_STATE_IDLE;
3152 rw_i93_send_to_upper (p_resp);
3153 GKI_freebuf (p_resp);
3154 break;
3155
3156 case RW_I93_STATE_DETECT_NDEF:
3157 rw_i93_sm_detect_ndef (p_resp);
3158 GKI_freebuf (p_resp);
3159 break;
3160
3161 case RW_I93_STATE_READ_NDEF:
3162 rw_i93_sm_read_ndef (p_resp);
3163 /* p_resp may send upper lyaer */
3164 break;
3165
3166 case RW_I93_STATE_UPDATE_NDEF:
3167 rw_i93_sm_update_ndef (p_resp);
3168 GKI_freebuf (p_resp);
3169 break;
3170
3171 case RW_I93_STATE_FORMAT:
3172 rw_i93_sm_format (p_resp);
3173 GKI_freebuf (p_resp);
3174 break;
3175
3176 case RW_I93_STATE_SET_READ_ONLY:
3177 rw_i93_sm_set_read_only (p_resp);
3178 GKI_freebuf (p_resp);
3179 break;
3180
3181 case RW_I93_STATE_PRESENCE_CHECK:
3182 p_i93->state = RW_I93_STATE_IDLE;
3183 p_i93->sent_cmd = 0;
3184
3185 /* if any response, send presence check with ok */
3186 rw_data.status = NFC_STATUS_OK;
3187 (*(rw_cb.p_cback)) (RW_I93_PRESENCE_CHECK_EVT, &rw_data);
3188 GKI_freebuf (p_resp);
3189 break;
3190
3191 default:
3192 RW_TRACE_ERROR1 ("rw_i93_data_cback (): invalid state=%d", p_i93->state);
3193 GKI_freebuf (p_resp);
3194 break;
3195 }
3196
3197 #if (BT_TRACE_VERBOSE == TRUE)
3198 if (begin_state != p_i93->state)
3199 {
3200 RW_TRACE_DEBUG2 ("RW I93 state changed:<%s> -> <%s>",
3201 rw_i93_get_state_name (begin_state),
3202 rw_i93_get_state_name (p_i93->state));
3203 }
3204 #endif
3205 }
3206
3207 /*******************************************************************************
3208 **
3209 ** Function rw_i93_select
3210 **
3211 ** Description Initialise ISO 15693 RW
3212 **
3213 ** Returns NFC_STATUS_OK if success
3214 **
3215 *******************************************************************************/
rw_i93_select(UINT8 * p_uid)3216 tNFC_STATUS rw_i93_select (UINT8 *p_uid)
3217 {
3218 tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
3219 UINT8 uid[I93_UID_BYTE_LEN], *p;
3220
3221 RW_TRACE_DEBUG0 ("rw_i93_select ()");
3222
3223 NFC_SetStaticRfCback (rw_i93_data_cback);
3224
3225 p_i93->state = RW_I93_STATE_IDLE;
3226
3227 /* convert UID to big endian format - MSB(0xE0) in first byte */
3228 p = uid;
3229 STREAM_TO_ARRAY8 (p, p_uid);
3230
3231 rw_i93_get_product_version (uid);
3232
3233 return NFC_STATUS_OK;
3234 }
3235
3236 /*******************************************************************************
3237 **
3238 ** Function RW_I93Inventory
3239 **
3240 ** Description This function send Inventory command with/without AFI
3241 ** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
3242 **
3243 ** RW_I93_RESPONSE_EVT will be returned
3244 **
3245 ** Returns NFC_STATUS_OK if success
3246 ** NFC_STATUS_NO_BUFFERS if out of buffer
3247 ** NFC_STATUS_BUSY if busy
3248 ** NFC_STATUS_FAILED if other error
3249 **
3250 *******************************************************************************/
RW_I93Inventory(BOOLEAN including_afi,UINT8 afi,UINT8 * p_uid)3251 tNFC_STATUS RW_I93Inventory (BOOLEAN including_afi, UINT8 afi, UINT8 *p_uid)
3252 {
3253 tNFC_STATUS status;
3254
3255 RW_TRACE_API2 ("RW_I93Inventory (), including_afi:%d, AFI:0x%02X", including_afi, afi);
3256
3257 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3258 {
3259 RW_TRACE_ERROR1 ("RW_I93Inventory ():Unable to start command at state (0x%X)",
3260 rw_cb.tcb.i93.state);
3261 return NFC_STATUS_BUSY;
3262 }
3263
3264 status = rw_i93_send_cmd_inventory (p_uid, including_afi, afi);
3265
3266 if (status == NFC_STATUS_OK)
3267 {
3268 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3269 }
3270
3271 return (status);
3272 }
3273
3274 /*******************************************************************************
3275 **
3276 ** Function RW_I93StayQuiet
3277 **
3278 ** Description This function send Inventory command
3279 **
3280 ** RW_I93_CMD_CMPL_EVT will be returned
3281 **
3282 ** Returns NFC_STATUS_OK if success
3283 ** NFC_STATUS_NO_BUFFERS if out of buffer
3284 ** NFC_STATUS_BUSY if busy
3285 ** NFC_STATUS_FAILED if other error
3286 **
3287 *******************************************************************************/
RW_I93StayQuiet(void)3288 tNFC_STATUS RW_I93StayQuiet (void)
3289 {
3290 tNFC_STATUS status;
3291
3292 RW_TRACE_API0 ("RW_I93StayQuiet ()");
3293
3294 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3295 {
3296 RW_TRACE_ERROR1 ("RW_I93StayQuiet ():Unable to start command at state (0x%X)",
3297 rw_cb.tcb.i93.state);
3298 return NFC_STATUS_BUSY;
3299 }
3300
3301 status = rw_i93_send_cmd_stay_quiet ();
3302 if (status == NFC_STATUS_OK)
3303 {
3304 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3305 }
3306
3307 return status;
3308 }
3309
3310 /*******************************************************************************
3311 **
3312 ** Function RW_I93ReadSingleBlock
3313 **
3314 ** Description This function send Read Single Block command
3315 **
3316 ** RW_I93_RESPONSE_EVT will be returned
3317 **
3318 ** Returns NFC_STATUS_OK if success
3319 ** NFC_STATUS_NO_BUFFERS if out of buffer
3320 ** NFC_STATUS_BUSY if busy
3321 ** NFC_STATUS_FAILED if other error
3322 **
3323 *******************************************************************************/
RW_I93ReadSingleBlock(UINT16 block_number)3324 tNFC_STATUS RW_I93ReadSingleBlock (UINT16 block_number)
3325 {
3326 tNFC_STATUS status;
3327
3328 RW_TRACE_API1 ("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
3329
3330 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3331 {
3332 RW_TRACE_ERROR1 ("RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
3333 rw_cb.tcb.i93.state);
3334 return NFC_STATUS_BUSY;
3335 }
3336
3337 status = rw_i93_send_cmd_read_single_block (block_number, FALSE);
3338 if (status == NFC_STATUS_OK)
3339 {
3340 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3341 }
3342
3343 return status;
3344 }
3345
3346 /*******************************************************************************
3347 **
3348 ** Function RW_I93WriteSingleBlock
3349 **
3350 ** Description This function send Write Single Block command
3351 ** Application must get block size first by calling RW_I93GetSysInfo().
3352 **
3353 ** RW_I93_CMD_CMPL_EVT will be returned
3354 **
3355 ** Returns NFC_STATUS_OK if success
3356 ** NFC_STATUS_NO_BUFFERS if out of buffer
3357 ** NFC_STATUS_BUSY if busy
3358 ** NFC_STATUS_FAILED if other error
3359 **
3360 *******************************************************************************/
RW_I93WriteSingleBlock(UINT16 block_number,UINT8 * p_data)3361 tNFC_STATUS RW_I93WriteSingleBlock (UINT16 block_number,
3362 UINT8 *p_data)
3363 {
3364 tNFC_STATUS status;
3365
3366 RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
3367
3368 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3369 {
3370 RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
3371 rw_cb.tcb.i93.state);
3372 return NFC_STATUS_BUSY;
3373 }
3374
3375 if (rw_cb.tcb.i93.block_size == 0)
3376 {
3377 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3378 return NFC_STATUS_FAILED;
3379 }
3380
3381 status = rw_i93_send_cmd_write_single_block (block_number, p_data);
3382 if (status == NFC_STATUS_OK)
3383 {
3384 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3385 }
3386
3387 return status;
3388 }
3389
3390 /*******************************************************************************
3391 **
3392 ** Function RW_I93LockBlock
3393 **
3394 ** Description This function send Lock Block command
3395 **
3396 ** RW_I93_CMD_CMPL_EVT will be returned
3397 **
3398 ** Returns NFC_STATUS_OK if success
3399 ** NFC_STATUS_NO_BUFFERS if out of buffer
3400 ** NFC_STATUS_BUSY if busy
3401 ** NFC_STATUS_FAILED if other error
3402 **
3403 *******************************************************************************/
RW_I93LockBlock(UINT8 block_number)3404 tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
3405 {
3406 tNFC_STATUS status;
3407
3408 RW_TRACE_API0 ("RW_I93LockBlock ()");
3409
3410 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3411 {
3412 RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
3413 rw_cb.tcb.i93.state);
3414 return NFC_STATUS_BUSY;
3415 }
3416
3417 status = rw_i93_send_cmd_lock_block (block_number);
3418 if (status == NFC_STATUS_OK)
3419 {
3420 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3421 }
3422
3423 return status;
3424 }
3425
3426 /*******************************************************************************
3427 **
3428 ** Function RW_I93ReadMultipleBlocks
3429 **
3430 ** Description This function send Read Multiple Blocks command
3431 **
3432 ** RW_I93_RESPONSE_EVT will be returned
3433 **
3434 ** Returns NFC_STATUS_OK if success
3435 ** NFC_STATUS_NO_BUFFERS if out of buffer
3436 ** NFC_STATUS_BUSY if busy
3437 ** NFC_STATUS_FAILED if other error
3438 **
3439 *******************************************************************************/
RW_I93ReadMultipleBlocks(UINT16 first_block_number,UINT16 number_blocks)3440 tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
3441 UINT16 number_blocks)
3442 {
3443 tNFC_STATUS status;
3444
3445 RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
3446
3447 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3448 {
3449 RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
3450 rw_cb.tcb.i93.state);
3451 return NFC_STATUS_BUSY;
3452 }
3453
3454 status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
3455 if (status == NFC_STATUS_OK)
3456 {
3457 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3458 }
3459
3460 return status;
3461 }
3462
3463 /*******************************************************************************
3464 **
3465 ** Function RW_I93WriteMultipleBlocks
3466 **
3467 ** Description This function send Write Multiple Blocks command
3468 **
3469 ** RW_I93_CMD_CMPL_EVT will be returned
3470 **
3471 ** Returns NFC_STATUS_OK if success
3472 ** NFC_STATUS_NO_BUFFERS if out of buffer
3473 ** NFC_STATUS_BUSY if busy
3474 ** NFC_STATUS_FAILED if other error
3475 **
3476 *******************************************************************************/
RW_I93WriteMultipleBlocks(UINT8 first_block_number,UINT16 number_blocks,UINT8 * p_data)3477 tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
3478 UINT16 number_blocks,
3479 UINT8 *p_data)
3480 {
3481 tNFC_STATUS status;
3482
3483 RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
3484
3485 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3486 {
3487 RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
3488 rw_cb.tcb.i93.state);
3489 return NFC_STATUS_BUSY;
3490 }
3491
3492 if (rw_cb.tcb.i93.block_size == 0)
3493 {
3494 RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
3495 return NFC_STATUS_FAILED;
3496 }
3497
3498 status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
3499 if (status == NFC_STATUS_OK)
3500 {
3501 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3502 }
3503
3504 return status;
3505 }
3506
3507 /*******************************************************************************
3508 **
3509 ** Function RW_I93Select
3510 **
3511 ** Description This function send Select command
3512 **
3513 ** UID[0]: 0xE0, MSB
3514 ** UID[1]: IC Mfg Code
3515 ** ...
3516 ** UID[7]: LSB
3517 **
3518 ** RW_I93_CMD_CMPL_EVT will be returned
3519 **
3520 ** Returns NFC_STATUS_OK if success
3521 ** NFC_STATUS_NO_BUFFERS if out of buffer
3522 ** NFC_STATUS_BUSY if busy
3523 ** NFC_STATUS_FAILED if other error
3524 **
3525 *******************************************************************************/
RW_I93Select(UINT8 * p_uid)3526 tNFC_STATUS RW_I93Select (UINT8 *p_uid)
3527 {
3528 tNFC_STATUS status;
3529
3530 RW_TRACE_API0 ("RW_I93Select ()");
3531
3532 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3533 {
3534 RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
3535 rw_cb.tcb.i93.state);
3536 return NFC_STATUS_BUSY;
3537 }
3538
3539 if (p_uid)
3540 {
3541 status = rw_i93_send_cmd_select (p_uid);
3542 if (status == NFC_STATUS_OK)
3543 {
3544 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3545 }
3546 }
3547 else
3548 {
3549 RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
3550 status = NFC_STATUS_FAILED;
3551 }
3552
3553 return status;
3554 }
3555
3556 /*******************************************************************************
3557 **
3558 ** Function RW_I93ResetToReady
3559 **
3560 ** Description This function send Reset To Ready command
3561 **
3562 ** RW_I93_CMD_CMPL_EVT will be returned
3563 **
3564 ** Returns NFC_STATUS_OK if success
3565 ** NFC_STATUS_NO_BUFFERS if out of buffer
3566 ** NFC_STATUS_BUSY if busy
3567 ** NFC_STATUS_FAILED if other error
3568 **
3569 *******************************************************************************/
RW_I93ResetToReady(void)3570 tNFC_STATUS RW_I93ResetToReady (void)
3571 {
3572 tNFC_STATUS status;
3573
3574 RW_TRACE_API0 ("RW_I93ResetToReady ()");
3575
3576 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3577 {
3578 RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
3579 rw_cb.tcb.i93.state);
3580 return NFC_STATUS_BUSY;
3581 }
3582
3583 status = rw_i93_send_cmd_reset_to_ready ();
3584 if (status == NFC_STATUS_OK)
3585 {
3586 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3587 }
3588
3589 return status;
3590 }
3591
3592 /*******************************************************************************
3593 **
3594 ** Function RW_I93WriteAFI
3595 **
3596 ** Description This function send Write AFI command
3597 **
3598 ** RW_I93_CMD_CMPL_EVT will be returned
3599 **
3600 ** Returns NFC_STATUS_OK if success
3601 ** NFC_STATUS_NO_BUFFERS if out of buffer
3602 ** NFC_STATUS_BUSY if busy
3603 ** NFC_STATUS_FAILED if other error
3604 **
3605 *******************************************************************************/
RW_I93WriteAFI(UINT8 afi)3606 tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
3607 {
3608 tNFC_STATUS status;
3609
3610 RW_TRACE_API0 ("RW_I93WriteAFI ()");
3611
3612 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3613 {
3614 RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
3615 rw_cb.tcb.i93.state);
3616 return NFC_STATUS_BUSY;
3617 }
3618
3619 status = rw_i93_send_cmd_write_afi (afi);
3620 if (status == NFC_STATUS_OK)
3621 {
3622 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3623 }
3624
3625 return status;
3626 }
3627
3628 /*******************************************************************************
3629 **
3630 ** Function RW_I93LockAFI
3631 **
3632 ** Description This function send Lock AFI command
3633 **
3634 ** RW_I93_CMD_CMPL_EVT will be returned
3635 **
3636 ** Returns NFC_STATUS_OK if success
3637 ** NFC_STATUS_NO_BUFFERS if out of buffer
3638 ** NFC_STATUS_BUSY if busy
3639 ** NFC_STATUS_FAILED if other error
3640 **
3641 *******************************************************************************/
RW_I93LockAFI(void)3642 tNFC_STATUS RW_I93LockAFI (void)
3643 {
3644 tNFC_STATUS status;
3645
3646 RW_TRACE_API0 ("RW_I93LockAFI ()");
3647
3648 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3649 {
3650 RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
3651 rw_cb.tcb.i93.state);
3652 return NFC_STATUS_BUSY;
3653 }
3654
3655 status = rw_i93_send_cmd_lock_afi ();
3656 if (status == NFC_STATUS_OK)
3657 {
3658 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3659 }
3660
3661 return status;
3662 }
3663
3664 /*******************************************************************************
3665 **
3666 ** Function RW_I93WriteDSFID
3667 **
3668 ** Description This function send Write DSFID command
3669 **
3670 ** RW_I93_CMD_CMPL_EVT will be returned
3671 **
3672 ** Returns NFC_STATUS_OK if success
3673 ** NFC_STATUS_NO_BUFFERS if out of buffer
3674 ** NFC_STATUS_BUSY if busy
3675 ** NFC_STATUS_FAILED if other error
3676 **
3677 *******************************************************************************/
RW_I93WriteDSFID(UINT8 dsfid)3678 tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
3679 {
3680 tNFC_STATUS status;
3681
3682 RW_TRACE_API0 ("RW_I93WriteDSFID ()");
3683
3684 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3685 {
3686 RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
3687 rw_cb.tcb.i93.state);
3688 return NFC_STATUS_BUSY;
3689 }
3690
3691 status = rw_i93_send_cmd_write_dsfid (dsfid);
3692 if (status == NFC_STATUS_OK)
3693 {
3694 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3695 }
3696
3697 return status;
3698 }
3699
3700 /*******************************************************************************
3701 **
3702 ** Function RW_I93LockDSFID
3703 **
3704 ** Description This function send Lock DSFID command
3705 **
3706 ** RW_I93_CMD_CMPL_EVT will be returned
3707 **
3708 ** Returns NFC_STATUS_OK if success
3709 ** NFC_STATUS_NO_BUFFERS if out of buffer
3710 ** NFC_STATUS_BUSY if busy
3711 ** NFC_STATUS_FAILED if other error
3712 **
3713 *******************************************************************************/
RW_I93LockDSFID(void)3714 tNFC_STATUS RW_I93LockDSFID (void)
3715 {
3716 tNFC_STATUS status;
3717
3718 RW_TRACE_API0 ("RW_I93LockDSFID ()");
3719
3720 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3721 {
3722 RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
3723 rw_cb.tcb.i93.state);
3724 return NFC_STATUS_BUSY;
3725 }
3726
3727 status = rw_i93_send_cmd_lock_dsfid ();
3728 if (status == NFC_STATUS_OK)
3729 {
3730 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3731 }
3732
3733 return status;
3734 }
3735
3736 /*******************************************************************************
3737 **
3738 ** Function RW_I93GetSysInfo
3739 **
3740 ** Description This function send Get System Information command
3741 **
3742 ** RW_I93_RESPONSE_EVT will be returned
3743 **
3744 ** Returns NFC_STATUS_OK if success
3745 ** NFC_STATUS_NO_BUFFERS if out of buffer
3746 ** NFC_STATUS_BUSY if busy
3747 ** NFC_STATUS_FAILED if other error
3748 **
3749 *******************************************************************************/
RW_I93GetSysInfo(UINT8 * p_uid)3750 tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
3751 {
3752 tNFC_STATUS status;
3753
3754 RW_TRACE_API0 ("RW_I93GetSysInfo ()");
3755
3756 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3757 {
3758 RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
3759 rw_cb.tcb.i93.state);
3760 return NFC_STATUS_BUSY;
3761 }
3762
3763 if (p_uid)
3764 {
3765 status = rw_i93_send_cmd_get_sys_info (p_uid, I93_FLAG_PROT_EXT_NO);
3766 }
3767 else
3768 {
3769 status = rw_i93_send_cmd_get_sys_info (NULL, I93_FLAG_PROT_EXT_NO);
3770 }
3771
3772 if (status == NFC_STATUS_OK)
3773 {
3774 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3775 }
3776
3777 return status;
3778 }
3779
3780 /*******************************************************************************
3781 **
3782 ** Function RW_I93GetMultiBlockSecurityStatus
3783 **
3784 ** Description This function send Get Multiple Block Security Status command
3785 **
3786 ** RW_I93_RESPONSE_EVT will be returned
3787 **
3788 ** Returns NFC_STATUS_OK if success
3789 ** NFC_STATUS_NO_BUFFERS if out of buffer
3790 ** NFC_STATUS_BUSY if busy
3791 ** NFC_STATUS_FAILED if other error
3792 **
3793 *******************************************************************************/
RW_I93GetMultiBlockSecurityStatus(UINT16 first_block_number,UINT16 number_blocks)3794 tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT16 first_block_number,
3795 UINT16 number_blocks)
3796 {
3797 tNFC_STATUS status;
3798
3799 RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
3800
3801 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3802 {
3803 RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
3804 rw_cb.tcb.i93.state);
3805 return NFC_STATUS_BUSY;
3806 }
3807
3808 status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
3809 if (status == NFC_STATUS_OK)
3810 {
3811 rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
3812 }
3813
3814 return status;
3815 }
3816
3817 /*******************************************************************************
3818 **
3819 ** Function RW_I93DetectNDef
3820 **
3821 ** Description This function performs NDEF detection procedure
3822 **
3823 ** RW_I93_NDEF_DETECT_EVT will be returned
3824 **
3825 ** Returns NFC_STATUS_OK if success
3826 ** NFC_STATUS_FAILED if busy or other error
3827 **
3828 *******************************************************************************/
RW_I93DetectNDef(void)3829 tNFC_STATUS RW_I93DetectNDef (void)
3830 {
3831 tNFC_STATUS status;
3832 tRW_I93_RW_SUBSTATE sub_state;
3833
3834 RW_TRACE_API0 ("RW_I93DetectNDef ()");
3835
3836 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3837 {
3838 RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
3839 rw_cb.tcb.i93.state);
3840 return NFC_STATUS_FAILED;
3841 }
3842
3843 if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
3844 {
3845 status = rw_i93_send_cmd_inventory (NULL, FALSE, 0x00);
3846 sub_state = RW_I93_SUBSTATE_WAIT_UID;
3847 }
3848 else if ( (rw_cb.tcb.i93.num_block == 0)
3849 ||(rw_cb.tcb.i93.block_size == 0) )
3850 {
3851 status = rw_i93_send_cmd_get_sys_info (rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
3852 sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
3853
3854 /* clear all flags */
3855 rw_cb.tcb.i93.intl_flags = 0;
3856 }
3857 else
3858 {
3859 /* read CC in the first block */
3860 status = rw_i93_send_cmd_read_single_block (0x0000, FALSE);
3861 sub_state = RW_I93_SUBSTATE_WAIT_CC;
3862 }
3863
3864 if (status == NFC_STATUS_OK)
3865 {
3866 rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
3867 rw_cb.tcb.i93.sub_state = sub_state;
3868
3869 /* clear flags except flag for 2 bytes of number of blocks */
3870 rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
3871 }
3872
3873 return (status);
3874 }
3875
3876 /*******************************************************************************
3877 **
3878 ** Function RW_I93ReadNDef
3879 **
3880 ** Description This function performs NDEF read procedure
3881 ** Note: RW_I93DetectNDef () must be called before using this
3882 **
3883 ** The following event will be returned
3884 ** RW_I93_NDEF_READ_EVT for each segmented NDEF message
3885 ** RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
3886 ** RW_I93_NDEF_READ_FAIL_EVT for failure
3887 **
3888 ** Returns NFC_STATUS_OK if success
3889 ** NFC_STATUS_FAILED if I93 is busy or other error
3890 **
3891 *******************************************************************************/
RW_I93ReadNDef(void)3892 tNFC_STATUS RW_I93ReadNDef (void)
3893 {
3894 RW_TRACE_API0 ("RW_I93ReadNDef ()");
3895
3896 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3897 {
3898 RW_TRACE_ERROR1 ("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
3899 rw_cb.tcb.i93.state);
3900 return NFC_STATUS_FAILED;
3901 }
3902
3903 if ( (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3904 &&(rw_cb.tcb.i93.ndef_length > 0) )
3905 {
3906 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
3907 rw_cb.tcb.i93.rw_length = 0;
3908
3909 if (rw_i93_get_next_blocks (rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK)
3910 {
3911 rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
3912 }
3913 else
3914 {
3915 return NFC_STATUS_FAILED;
3916 }
3917 }
3918 else
3919 {
3920 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3921 return NFC_STATUS_FAILED;
3922 }
3923
3924 return NFC_STATUS_OK;
3925 }
3926
3927 /*******************************************************************************
3928 **
3929 ** Function RW_I93UpdateNDef
3930 **
3931 ** Description This function performs NDEF update procedure
3932 ** Note: RW_I93DetectNDef () must be called before using this
3933 ** Updating data must not be removed until returning event
3934 **
3935 ** The following event will be returned
3936 ** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
3937 ** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
3938 **
3939 ** Returns NFC_STATUS_OK if success
3940 ** NFC_STATUS_FAILED if I93 is busy or other error
3941 **
3942 *******************************************************************************/
RW_I93UpdateNDef(UINT16 length,UINT8 * p_data)3943 tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data)
3944 {
3945 UINT16 block_number;
3946
3947 RW_TRACE_API1 ("RW_I93UpdateNDef () length:%d", length);
3948
3949 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
3950 {
3951 RW_TRACE_ERROR1 ("RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
3952 rw_cb.tcb.i93.state);
3953 return NFC_STATUS_FAILED;
3954 }
3955
3956 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
3957 {
3958 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
3959 {
3960 RW_TRACE_ERROR0 ("RW_I93UpdateNDef ():NDEF is read-only");
3961 return NFC_STATUS_FAILED;
3962 }
3963 if (rw_cb.tcb.i93.max_ndef_length < length)
3964 {
3965 RW_TRACE_ERROR2 ("RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length (%d)",
3966 length, rw_cb.tcb.i93.max_ndef_length);
3967 return NFC_STATUS_FAILED;
3968 }
3969
3970 rw_cb.tcb.i93.ndef_length = length;
3971 rw_cb.tcb.i93.p_update_data = p_data;
3972
3973 /* read length field */
3974 rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
3975 rw_cb.tcb.i93.rw_length = 0;
3976
3977 block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
3978
3979 if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
3980 {
3981 rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
3982 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
3983 }
3984 else
3985 {
3986 return NFC_STATUS_FAILED;
3987 }
3988 }
3989 else
3990 {
3991 RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
3992 return NFC_STATUS_FAILED;
3993 }
3994
3995 return NFC_STATUS_OK;
3996 }
3997
3998 /*******************************************************************************
3999 **
4000 ** Function RW_I93FormatNDef
4001 **
4002 ** Description This function performs formatting procedure
4003 **
4004 ** RW_I93_FORMAT_CPLT_EVT will be returned
4005 **
4006 ** Returns NFC_STATUS_OK if success
4007 ** NFC_STATUS_FAILED if busy or other error
4008 **
4009 *******************************************************************************/
RW_I93FormatNDef(void)4010 tNFC_STATUS RW_I93FormatNDef (void)
4011 {
4012 tNFC_STATUS status;
4013 tRW_I93_RW_SUBSTATE sub_state;
4014
4015 RW_TRACE_API0 ("RW_I93FormatNDef ()");
4016
4017 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4018 {
4019 RW_TRACE_ERROR1 ("RW_I93FormatNDef ():Unable to start command at state (0x%X)",
4020 rw_cb.tcb.i93.state);
4021 return NFC_STATUS_FAILED;
4022 }
4023
4024 if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
4025 ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
4026 {
4027 /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus */
4028 rw_cb.tcb.i93.rw_offset = 0;
4029
4030 /* read blocks with option flag to get block security status */
4031 status = rw_i93_send_cmd_read_single_block (0x0000, TRUE);
4032 sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
4033 }
4034 else
4035 {
4036 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
4037 sub_state = RW_I93_SUBSTATE_WAIT_UID;
4038 }
4039
4040 if (status == NFC_STATUS_OK)
4041 {
4042 rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
4043 rw_cb.tcb.i93.sub_state = sub_state;
4044 rw_cb.tcb.i93.intl_flags = 0;
4045 }
4046
4047 return (status);
4048 }
4049
4050 /*******************************************************************************
4051 **
4052 ** Function RW_I93SetTagReadOnly
4053 **
4054 ** Description This function performs NDEF read-only procedure
4055 ** Note: RW_I93DetectNDef () must be called before using this
4056 ** Updating data must not be removed until returning event
4057 **
4058 ** The RW_I93_SET_TAG_RO_EVT event will be returned.
4059 **
4060 ** Returns NFC_STATUS_OK if success
4061 ** NFC_STATUS_FAILED if I93 is busy or other error
4062 **
4063 *******************************************************************************/
RW_I93SetTagReadOnly(void)4064 tNFC_STATUS RW_I93SetTagReadOnly (void)
4065 {
4066 RW_TRACE_API0 ("RW_I93SetTagReadOnly ()");
4067
4068 if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4069 {
4070 RW_TRACE_ERROR1 ("RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
4071 rw_cb.tcb.i93.state);
4072 return NFC_STATUS_FAILED;
4073 }
4074
4075 if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
4076 {
4077 if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
4078 {
4079 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():NDEF is already read-only");
4080 return NFC_STATUS_FAILED;
4081 }
4082
4083 /* get CC in the first block */
4084 if (rw_i93_send_cmd_read_single_block (0, FALSE) == NFC_STATUS_OK)
4085 {
4086 rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
4087 rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
4088 }
4089 else
4090 {
4091 return NFC_STATUS_FAILED;
4092 }
4093 }
4094 else
4095 {
4096 RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():No NDEF detected");
4097 return NFC_STATUS_FAILED;
4098 }
4099
4100 return NFC_STATUS_OK;
4101 }
4102
4103 /*****************************************************************************
4104 **
4105 ** Function RW_I93PresenceCheck
4106 **
4107 ** Description Check if the tag is still in the field.
4108 **
4109 ** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
4110 ** presence or non-presence.
4111 **
4112 ** Returns NFC_STATUS_OK, if raw data frame sent
4113 ** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
4114 ** NFC_STATUS_FAILED: other error
4115 **
4116 *****************************************************************************/
RW_I93PresenceCheck(void)4117 tNFC_STATUS RW_I93PresenceCheck (void)
4118 {
4119
4120 tNFC_STATUS status;
4121 tRW_DATA evt_data;
4122
4123 RW_TRACE_API0 ("RW_I93PresenceCheck ()");
4124
4125 if (!rw_cb.p_cback)
4126 {
4127 return NFC_STATUS_FAILED;
4128 }
4129 else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED)
4130 {
4131 evt_data.status = NFC_STATUS_FAILED;
4132 (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
4133
4134 return NFC_STATUS_OK;
4135 }
4136 else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
4137 {
4138 return NFC_STATUS_BUSY;
4139 }
4140 else
4141 {
4142 /* The support of AFI by the VICC is optional, so do not include AFI */
4143 status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, FALSE, 0x00);
4144
4145 if (status == NFC_STATUS_OK)
4146 {
4147 /* do not retry during presence check */
4148 rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
4149 rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
4150 }
4151 }
4152
4153 return (status);
4154 }
4155
4156 #if (BT_TRACE_VERBOSE == TRUE)
4157 /*******************************************************************************
4158 **
4159 ** Function rw_i93_get_state_name
4160 **
4161 ** Description This function returns the state name.
4162 **
4163 ** NOTE conditionally compiled to save memory.
4164 **
4165 ** Returns pointer to the name
4166 **
4167 *******************************************************************************/
rw_i93_get_state_name(UINT8 state)4168 static char *rw_i93_get_state_name (UINT8 state)
4169 {
4170 switch (state)
4171 {
4172 case RW_I93_STATE_NOT_ACTIVATED:
4173 return ("NOT_ACTIVATED");
4174 case RW_I93_STATE_IDLE:
4175 return ("IDLE");
4176 case RW_I93_STATE_BUSY:
4177 return ("BUSY");
4178
4179 case RW_I93_STATE_DETECT_NDEF:
4180 return ("NDEF_DETECTION");
4181 case RW_I93_STATE_READ_NDEF:
4182 return ("READ_NDEF");
4183 case RW_I93_STATE_UPDATE_NDEF:
4184 return ("UPDATE_NDEF");
4185 case RW_I93_STATE_FORMAT:
4186 return ("FORMAT");
4187 case RW_I93_STATE_SET_READ_ONLY:
4188 return ("SET_READ_ONLY");
4189
4190 case RW_I93_STATE_PRESENCE_CHECK:
4191 return ("PRESENCE_CHECK");
4192 default:
4193 return ("???? UNKNOWN STATE");
4194 }
4195 }
4196
4197 /*******************************************************************************
4198 **
4199 ** Function rw_i93_get_sub_state_name
4200 **
4201 ** Description This function returns the sub_state name.
4202 **
4203 ** NOTE conditionally compiled to save memory.
4204 **
4205 ** Returns pointer to the name
4206 **
4207 *******************************************************************************/
rw_i93_get_sub_state_name(UINT8 sub_state)4208 static char *rw_i93_get_sub_state_name (UINT8 sub_state)
4209 {
4210 switch (sub_state)
4211 {
4212 case RW_I93_SUBSTATE_WAIT_UID:
4213 return ("WAIT_UID");
4214 case RW_I93_SUBSTATE_WAIT_SYS_INFO:
4215 return ("WAIT_SYS_INFO");
4216 case RW_I93_SUBSTATE_WAIT_CC:
4217 return ("WAIT_CC");
4218 case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
4219 return ("SEARCH_NDEF_TLV");
4220 case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
4221 return ("CHECK_LOCK_STATUS");
4222 case RW_I93_SUBSTATE_RESET_LEN:
4223 return ("RESET_LEN");
4224 case RW_I93_SUBSTATE_WRITE_NDEF:
4225 return ("WRITE_NDEF");
4226 case RW_I93_SUBSTATE_UPDATE_LEN:
4227 return ("UPDATE_LEN");
4228 case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
4229 return ("WAIT_RESET_DSFID_AFI");
4230 case RW_I93_SUBSTATE_CHECK_READ_ONLY:
4231 return ("CHECK_READ_ONLY");
4232 case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
4233 return ("WRITE_CC_NDEF_TLV");
4234 case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
4235 return ("WAIT_UPDATE_CC");
4236 case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
4237 return ("LOCK_NDEF_TLV");
4238 case RW_I93_SUBSTATE_WAIT_LOCK_CC:
4239 return ("WAIT_LOCK_CC");
4240 default:
4241 return ("???? UNKNOWN SUBSTATE");
4242 }
4243 }
4244
4245 /*******************************************************************************
4246 **
4247 ** Function rw_i93_get_tag_name
4248 **
4249 ** Description This function returns the tag name.
4250 **
4251 ** NOTE conditionally compiled to save memory.
4252 **
4253 ** Returns pointer to the name
4254 **
4255 *******************************************************************************/
rw_i93_get_tag_name(UINT8 product_version)4256 static char *rw_i93_get_tag_name (UINT8 product_version)
4257 {
4258 switch (product_version)
4259 {
4260 case RW_I93_ICODE_SLI:
4261 return ("SLI/SLIX");
4262 case RW_I93_ICODE_SLI_S:
4263 return ("SLI-S/SLIX-S");
4264 case RW_I93_ICODE_SLI_L:
4265 return ("SLI-L/SLIX-L");
4266 case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
4267 return ("Tag-it HF-I Plus Inlay");
4268 case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
4269 return ("Tag-it HF-I Plus Chip");
4270 case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
4271 return ("Tag-it HF-I Standard Chip/Inlyas");
4272 case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
4273 return ("Tag-it HF-I Pro Chip/Inlays");
4274 case RW_I93_STM_LRI1K:
4275 return ("LRi1K");
4276 case RW_I93_STM_LRI2K:
4277 return ("LRi2K");
4278 case RW_I93_STM_LRIS2K:
4279 return ("LRiS2K");
4280 case RW_I93_STM_LRIS64K:
4281 return ("LRiS64K");
4282 case RW_I93_STM_M24LR64_R:
4283 return ("M24LR64");
4284 case RW_I93_STM_M24LR04E_R:
4285 return ("M24LR04E");
4286 case RW_I93_STM_M24LR16E_R:
4287 return ("M24LR16E");
4288 case RW_I93_STM_M24LR64E_R:
4289 return ("M24LR64E");
4290 case RW_I93_UNKNOWN_PRODUCT:
4291 default:
4292 return ("UNKNOWN");
4293 }
4294 }
4295
4296 #endif
4297
4298 #endif /* (NFC_INCLUDED == TRUE) */
4299