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