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