• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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