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