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