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