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