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