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