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