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