xref: /aosp_15_r20/system/nfc/src/nfc/tags/rw_t4t.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-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 Type 4 tag in Reader/Writer
22  *  mode.
23  *
24  ******************************************************************************/
25 #include <android-base/logging.h>
26 #include <android-base/stringprintf.h>
27 #include <log/log.h>
28 #include <string.h>
29 
30 #include "bt_types.h"
31 #include "nfa_nfcee_int.h"
32 #include "nfa_rw_int.h"
33 #include "nfc_api.h"
34 #include "nfc_int.h"
35 #include "nfc_target.h"
36 #include "rw_api.h"
37 #include "rw_int.h"
38 
39 using android::base::StringPrintf;
40 
41 extern unsigned char appl_dta_mode_flag;
42 
43 /* main state */
44 /* T4T is not activated                 */
45 #define RW_T4T_STATE_NOT_ACTIVATED 0x00
46 /* waiting for upper layer API          */
47 #define RW_T4T_STATE_IDLE 0x01
48 /* performing NDEF detection precedure  */
49 #define RW_T4T_STATE_DETECT_NDEF 0x02
50 /* performing read NDEF procedure       */
51 #define RW_T4T_STATE_READ_NDEF 0x03
52 /* performing update NDEF procedure     */
53 #define RW_T4T_STATE_UPDATE_NDEF 0x04
54 /* checking presence of tag             */
55 #define RW_T4T_STATE_PRESENCE_CHECK 0x05
56 /* convert tag to read only             */
57 #define RW_T4T_STATE_SET_READ_ONLY 0x06
58 
59 /* performing NDEF format               */
60 #define RW_T4T_STATE_NDEF_FORMAT 0x07
61 
62 /* sub state */
63 /* waiting for response of selecting AID    */
64 #define RW_T4T_SUBSTATE_WAIT_SELECT_APP 0x00
65 /* waiting for response of selecting CC     */
66 #define RW_T4T_SUBSTATE_WAIT_SELECT_CC 0x01
67 /* waiting for response of reading CC       */
68 #define RW_T4T_SUBSTATE_WAIT_CC_FILE 0x02
69 /* waiting for response of selecting NDEF   */
70 #define RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE 0x03
71 /* waiting for response of reading NLEN     */
72 #define RW_T4T_SUBSTATE_WAIT_READ_NLEN 0x04
73 /* waiting for response of reading file     */
74 #define RW_T4T_SUBSTATE_WAIT_READ_RESP 0x05
75 /* waiting for response of updating file    */
76 #define RW_T4T_SUBSTATE_WAIT_UPDATE_RESP 0x06
77 /* waiting for response of updating NLEN    */
78 #define RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN 0x07
79 /* waiting for response of updating CC      */
80 #define RW_T4T_SUBSTATE_WAIT_UPDATE_CC 0x08
81 /* waiting for response of reading CC       */
82 #define RW_T4T_SUBSTATE_WAIT_ENDEF_FILE_CTRL_TLV 0x11
83 #define RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION 0x09
84 #define RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION 0x0A
85 #define RW_T4T_SUBSTATE_WAIT_GET_UID 0x0B
86 #define RW_T4T_SUBSTATE_WAIT_CREATE_APP 0x0C
87 #define RW_T4T_SUBSTATE_WAIT_CREATE_CC 0x0D
88 #define RW_T4T_SUBSTATE_WAIT_CREATE_NDEF 0x0E
89 #define RW_T4T_SUBSTATE_WAIT_WRITE_CC 0x0F
90 #define RW_T4T_SUBSTATE_WAIT_WRITE_NDEF 0x10
91 
92 static std::string rw_t4t_get_state_name(uint8_t state);
93 static std::string rw_t4t_get_sub_state_name(uint8_t sub_state);
94 
95 static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu);
96 static bool rw_t4t_select_file(uint16_t file_id);
97 static bool rw_t4t_read_file(uint32_t offset, uint32_t length,
98                              bool is_continue);
99 static bool rw_t4t_update_nlen(uint32_t ndef_len);
100 static bool rw_t4t_update_file(void);
101 static bool rw_t4t_update_cc_to_readonly(void);
102 static bool rw_t4t_select_application(uint8_t version);
103 static bool rw_t4t_validate_cc_file(void);
104 
105 static bool rw_t4t_get_hw_version(void);
106 static bool rw_t4t_get_sw_version(void);
107 static bool rw_t4t_create_app(void);
108 static bool rw_t4t_select_app(void);
109 static bool rw_t4t_create_ccfile(void);
110 static bool rw_t4t_create_ndef(void);
111 static bool rw_t4t_write_cc(void);
112 static bool rw_t4t_write_ndef(void);
113 static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2);
114 static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu);
115 static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu);
116 static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu);
117 static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu);
118 static void rw_t4t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
119                               tNFC_CONN* p_data);
120 static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu);
121 
122 /*******************************************************************************
123 **
124 ** Function         rw_t4t_send_to_lower
125 **
126 ** Description      Send C-APDU to lower layer
127 **
128 ** Returns          TRUE if success
129 **
130 *******************************************************************************/
rw_t4t_send_to_lower(NFC_HDR * p_c_apdu)131 static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu) {
132   uint8_t conn_id = NFC_RF_CONN_ID;
133 
134   if (rw_cb.tcb.t4t.p_retry_cmd) {
135     GKI_freebuf(rw_cb.tcb.t4t.p_retry_cmd);
136     rw_cb.tcb.t4t.p_retry_cmd = nullptr;
137   }
138 
139   uint16_t msg_size = sizeof(NFC_HDR) + p_c_apdu->offset + p_c_apdu->len;
140 
141   rw_cb.tcb.t4t.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
142 
143   if (rw_cb.tcb.t4t.p_retry_cmd &&
144       GKI_get_pool_bufsize(NFC_RW_POOL_ID) >= msg_size) {
145     memcpy(rw_cb.tcb.t4t.p_retry_cmd, p_c_apdu, msg_size);
146   } else {
147     LOG(ERROR) << StringPrintf("Memory allocation error");
148     return false;
149   }
150   if (NFA_T4tNfcEeIsProcessing()) {
151     conn_id = nfa_t4tnfcee_cb.connId;
152   }
153   LOG(DEBUG) << StringPrintf("%s - conn_id sent to lower : %d", __func__,
154                              conn_id);
155   if (NFC_SendData(conn_id, p_c_apdu) != NFC_STATUS_OK) {
156     LOG(ERROR) << StringPrintf("failed");
157     return false;
158   }
159 
160   nfc_start_quick_timer(&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
161                         (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
162 
163   return true;
164 }
165 
166 /*******************************************************************************
167 **
168 ** Function         rw_t4t_set_ber_tlv
169 **
170 ** Description      Send UpdateBinary Command with ODO and DDO
171 **
172 ** Returns          TRUE if success
173 **
174 *******************************************************************************/
rw_t4t_set_ber_tlv(NFC_HDR * p_c_apdu,uint8_t * p,uint32_t length)175 static bool rw_t4t_set_ber_tlv(NFC_HDR* p_c_apdu, uint8_t* p, uint32_t length) {
176   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
177   uint32_t data_length, tmp_length, tmp_offset;
178   uint8_t length_size, data_header = 0;
179 
180   p_c_apdu->len = T4T_CMD_MIN_EXT_HDR_SIZE + 1; /* tag 53 */
181   /* Remove min data header for encoding offset and data length */
182   /* length is Lc data length */
183   /* data_length is the length of the data to be written to the ENDEF
184    * File */
185   data_length = length;
186   if (length <= 0x7F) {
187     /* Default Short Field Coding can be used */
188     /* BER-TLV length coded on one byte */
189     length_size = RW_T4T_BER_TLV_LENGTH_1_BYTE;
190 
191   } else if ((length + RW_T4T_ODO_DDO_HEADER_2BYTES_LENGTH) <= 0xFF) {
192     /* Default Short Field Coding can be used */
193     /* BER-TLV length coded on two bytes: (81h+N) with N=0 to 255 */
194     length_size = RW_T4T_BER_TLV_LENGTH_2_BYTES;
195 
196   } else {
197     if (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING) {
198       /* Extended Field Coding can be used */
199       if (length <= 0xFF) {
200         LOG(VERBOSE) << StringPrintf(
201             "%s - Extended Field Coding used, 2-byte coding "
202             "for BER-TLV",
203             __func__);
204         /* BER-TLV length coded on two bytes still possible */
205         length_size = RW_T4T_BER_TLV_LENGTH_2_BYTES;
206 
207       } else {
208         LOG(VERBOSE) << StringPrintf(
209             "%s - Extended Field Coding used, 3-byte coding "
210             "for BER-TLV",
211             __func__);
212         /* BER-TLV length coded on three bytes:
213          * (82h+N) with N=0 to 65535 */
214         length_size = RW_T4T_BER_TLV_LENGTH_3_BYTES;
215       }
216     } else {
217       LOG(VERBOSE) << StringPrintf("%s - Short Field Coding used", __func__);
218       /* Only Short Field Coding can be used */
219       /* Write a max of 255 bytes in data field,
220        * as Lc=00 is reserved for Extended Field coding */
221       /* BER-TLV length coded on two bytes */
222       length_size = RW_T4T_BER_TLV_LENGTH_2_BYTES;
223       length = 0;
224     }
225   }
226 
227   data_header = RW_T4T_ODO_DDO_HEADER_MIN_LENGTH + length_size;
228   if (length == 0) {
229     length = T4T_MAX_LENGTH_LC;
230     if (length <= p_t4t->max_update_size) {
231       data_length = T4T_MAX_LENGTH_LC - data_header;
232     } else {
233       /* Realign with MLc (taking into account header now) */
234       length = p_t4t->max_update_size;
235       data_length = p_t4t->max_update_size - data_header;
236     }
237   } else {
238     if ((length + data_header) <= p_t4t->max_update_size) {
239       length += data_header;
240     } else {
241       /* Realign with MLc (taking into account header now) */
242       length = p_t4t->max_update_size;
243       data_length = p_t4t->max_update_size - data_header;
244     }
245   }
246 
247   UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
248   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY_ODO);
249   /* P1 P2 field */
250   UINT16_TO_BE_STREAM(p, 0x0000);
251   /* Lc field */
252   if (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING) {
253     /* Coded over three bytes */
254     UINT8_TO_BE_STREAM(p, 0x00);
255     tmp_length = length;
256     tmp_length >>= 8;
257     UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_length));
258     tmp_length = length;
259     UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_length));
260     p_c_apdu->len += 3;
261   } else {
262     /* Coded over 1 byte */
263     UINT8_TO_BE_STREAM(p, ((uint8_t)length));
264     p_c_apdu->len += 1;
265   }
266 
267   /* Data field containing data offset coded over 3 bytes
268    * followed by data to be written to the ENDEF File */
269   UINT16_TO_BE_STREAM(p, 0x5403);
270   tmp_offset = p_t4t->rw_offset;
271   tmp_offset >>= 16;
272   UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
273   tmp_offset = p_t4t->rw_offset;
274   tmp_offset >>= 8;
275   UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
276   tmp_offset = p_t4t->rw_offset;
277   UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
278 
279   UINT8_TO_BE_STREAM(p, 0x53);
280   /* Data length */
281   if (length_size == RW_T4T_BER_TLV_LENGTH_1_BYTE) {
282     /* Length coded over 1 byte */
283     UINT8_TO_BE_STREAM(p, data_length);
284     p_c_apdu->len += 1;
285   } else if (length_size == RW_T4T_BER_TLV_LENGTH_2_BYTES) {
286     UINT8_TO_BE_STREAM(p, 0x81);
287     UINT8_TO_BE_STREAM(p, data_length);
288     p_c_apdu->len += 2;
289   } else if ((length_size == RW_T4T_BER_TLV_LENGTH_3_BYTES) &&
290              (data_length <= 0xFFFF)) {
291     /* Length coded over 3 bytes */
292     UINT8_TO_BE_STREAM(p, 0x82);
293     UINT16_TO_BE_STREAM(p, (uint16_t)data_length);
294     p_c_apdu->len += 3;
295   } else {
296     LOG(ERROR) << StringPrintf(
297         "%s - Data to be written to MV3.0 tag exceeds 0xFFFF", __func__);
298     return false;
299   }
300 
301   memcpy(p, p_t4t->p_update_data, data_length);
302 
303   p_c_apdu->len += data_length;
304 
305   if (!rw_t4t_send_to_lower(p_c_apdu)) {
306     return false;
307   }
308   /* Le field not present */
309 
310   /* adjust offset, length and pointer for remaining data */
311   p_t4t->rw_offset += data_length;
312   p_t4t->rw_length -= data_length;
313   p_t4t->p_update_data += data_length;
314 
315   return true;
316 }
317 
318 /*******************************************************************************
319 **
320 ** Function         rw_t4t_format_short_field_coding
321 **
322 ** Description      Reformat Binary Command with Le coded over one byte instead
323 **                  of three bytes. Applicable to MV2.0 non compliant tags
324 **
325 ** Returns          none
326 **
327 *******************************************************************************/
rw_t4t_format_short_field_coding(void)328 static void rw_t4t_format_short_field_coding(void) {
329   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
330   uint8_t* p;
331   uint8_t* p_old_c_apdu;
332   NFC_HDR* p_new_c_apdu;
333   uint16_t old_Le_field;
334 
335   LOG(ERROR) << StringPrintf(
336       "%s; empty payload received, retry C-APDU with "
337       "Le in Short Field coding",
338       __func__);
339 
340   p_t4t->p_retry_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
341   p_old_c_apdu =
342       (uint8_t*)(p_t4t->p_retry_cmd + 1) + p_t4t->p_retry_cmd->offset;
343 
344   if ((*(p_old_c_apdu + 1) == T4T_CMD_INS_READ_BINARY) &&
345       (p_t4t->p_retry_cmd->len == T4T_CMD_MAX_EFC_NO_LC_HDR_SIZE)) {
346     /* Reformat C-APDU with Le Short Field Coded on one byte */
347 
348     /* Note: Le configuration 00h for first byte followed by 0000h is
349      * not used in the command coding */
350     old_Le_field = *(p_old_c_apdu + 5);
351     old_Le_field <<= 8;
352     old_Le_field |= (uint16_t)*(p_old_c_apdu + 6);
353 
354     LOG(DEBUG) << StringPrintf(
355         "%s; Reformat C-APDU with Le Short Field coded on one byte", __func__);
356     p_new_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
357 
358     if (p_new_c_apdu == nullptr) {
359       LOG(ERROR) << StringPrintf("%s; Cannot allocate buffer", __func__);
360       return;
361     }
362 
363     p_new_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
364     p = (uint8_t*)(p_new_c_apdu + 1) + p_new_c_apdu->offset;
365 
366     /* Copy CLA + INS + P1 + P2 from original command */
367     memcpy(p, p_old_c_apdu, T4T_CMD_MIN_HDR_SIZE);
368 
369     if (old_Le_field <= 0xFF) {
370       /* Copy least significant byte of Le */
371       *(p + T4T_CMD_MIN_HDR_SIZE) = *(p_old_c_apdu + 6);
372     } else {
373       /* Limit length to read to 255 bytes (0x00 not used) */
374       *(p + T4T_CMD_MIN_HDR_SIZE) = 0xFF;
375     }
376 
377     p_new_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
378 
379     if (!rw_t4t_send_to_lower(p_new_c_apdu)) {
380       LOG(ERROR) << StringPrintf("%s; Error calling rw_t4t_send_to_lower()",
381                                  __func__);
382     }
383   }
384 }
385 
386 /*******************************************************************************
387 **
388 ** Function         rw_t4t_get_hw_version
389 **
390 ** Description      Send get hw version cmd to peer
391 **
392 ** Returns          TRUE if success
393 **
394 *******************************************************************************/
rw_t4t_get_hw_version(void)395 static bool rw_t4t_get_hw_version(void) {
396   NFC_HDR* p_c_apdu;
397   uint8_t* p;
398 
399   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
400 
401   if (!p_c_apdu) {
402     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
403     return false;
404   }
405 
406   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
407   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
408 
409   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
410   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_GET_HW_VERSION);
411   UINT16_TO_BE_STREAM(p, 0x0000);
412   UINT8_TO_BE_FIELD(p, 0x00);
413 
414   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
415 
416   if (!rw_t4t_send_to_lower(p_c_apdu)) {
417     return false;
418   }
419 
420   return true;
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function         rw_t4t_get_sw_version
426 **
427 ** Description      Send get sw version cmd to peer
428 **
429 ** Returns          TRUE if success
430 **
431 *******************************************************************************/
rw_t4t_get_sw_version(void)432 static bool rw_t4t_get_sw_version(void) {
433   NFC_HDR* p_c_apdu;
434   uint8_t* p;
435 
436   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
437 
438   if (!p_c_apdu) {
439     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
440     return false;
441   }
442 
443   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
444   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
445 
446   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
447   UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
448   UINT16_TO_BE_STREAM(p, 0x0000);
449   UINT8_TO_BE_FIELD(p, 0x00);
450 
451   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
452 
453   if (!rw_t4t_send_to_lower(p_c_apdu)) {
454     return false;
455   }
456 
457   return true;
458 }
459 
460 /*******************************************************************************
461 **
462 ** Function         rw_t4t_update_version_details
463 **
464 ** Description      Updates the size of the card
465 **
466 ** Returns          TRUE if success
467 **
468 *******************************************************************************/
rw_t4t_update_version_details(NFC_HDR * p_r_apdu)469 static bool rw_t4t_update_version_details(NFC_HDR* p_r_apdu) {
470   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
471   uint8_t* p;
472   uint16_t major_version, minor_version;
473 
474   if (p_r_apdu->len < T4T_DES_GET_VERSION_LEN) {
475     LOG(ERROR) << StringPrintf("%s incorrect p_r_apdu length", __func__);
476     android_errorWriteLog(0x534e4554, "120865977");
477     return false;
478   }
479 
480   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
481   major_version = *(p + 3);
482   minor_version = *(p + 4);
483 
484   if ((T4T_DESEV0_MAJOR_VERSION == major_version) &&
485       (T4T_DESEV0_MINOR_VERSION == minor_version)) {
486     p_t4t->card_size = 0xEDE;
487   } else if (major_version >= T4T_DESEV1_MAJOR_VERSION) {
488     p_t4t->card_type = T4T_TYPE_DESFIRE_EV1;
489     switch (*(p + 5)) {
490       case T4T_SIZE_IDENTIFIER_2K:
491         p_t4t->card_size = 2048;
492         break;
493       case T4T_SIZE_IDENTIFIER_4K:
494         p_t4t->card_size = 4096;
495         break;
496       case T4T_SIZE_IDENTIFIER_8K:
497         p_t4t->card_size = 7680;
498         break;
499       default:
500         return false;
501     }
502   } else {
503     return false;
504   }
505 
506   return true;
507 }
508 
509 /*******************************************************************************
510 **
511 ** Function         rw_t4t_get_uid_details
512 **
513 ** Description      Send get uid cmd to peer
514 **
515 ** Returns          TRUE if success
516 **
517 *******************************************************************************/
rw_t4t_get_uid_details(void)518 static bool rw_t4t_get_uid_details(void) {
519   NFC_HDR* p_c_apdu;
520   uint8_t* p;
521 
522   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
523 
524   if (!p_c_apdu) {
525     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
526     return false;
527   }
528 
529   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
530   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
531 
532   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
533   UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
534   UINT16_TO_BE_STREAM(p, 0x0000);
535   UINT8_TO_BE_FIELD(p, 0x00);
536 
537   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
538 
539   if (!rw_t4t_send_to_lower(p_c_apdu)) {
540     return false;
541   }
542 
543   return true;
544 }
545 
546 /*******************************************************************************
547 **
548 ** Function         rw_t4t_create_app
549 **
550 ** Description      Send create application cmd to peer
551 **
552 ** Returns          TRUE if success
553 **
554 *******************************************************************************/
rw_t4t_create_app(void)555 static bool rw_t4t_create_app(void) {
556   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
557   NFC_HDR* p_c_apdu;
558   uint8_t* p;
559   uint8_t df_name[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
560 
561   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
562 
563   if (!p_c_apdu) {
564     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
565     return false;
566   }
567 
568   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
569   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
570 
571   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
572   UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_AID);
573   UINT16_TO_BE_STREAM(p, 0x0000);
574   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
575     UINT8_TO_BE_STREAM(p, (T4T_CMD_MAX_HDR_SIZE + sizeof(df_name) + 2));
576     UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
577     UINT16_TO_BE_STREAM(p, 0x0F21); /*Key settings and no.of keys */
578     UINT16_TO_BE_STREAM(p, 0x05E1); /* ISO file ID */
579     ARRAY_TO_BE_STREAM(p, df_name, (int)sizeof(df_name)); /*DF file name */
580     UINT8_TO_BE_STREAM(p, 0x00);                          /* Le */
581     p_c_apdu->len = 20;
582   } else {
583     UINT8_TO_BE_STREAM(p, T4T_CMD_MAX_HDR_SIZE);
584     UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
585     UINT16_TO_BE_STREAM(p, 0x0F01); /*Key settings and no.of keys */
586     UINT8_TO_BE_STREAM(p, 0x00);    /* Le */
587     p_c_apdu->len = 11;
588   }
589 
590   if (!rw_t4t_send_to_lower(p_c_apdu)) {
591     return false;
592   }
593 
594   return true;
595 }
596 
597 /*******************************************************************************
598 **
599 ** Function         rw_t4t_select_app
600 **
601 ** Description      Select application cmd to peer
602 **
603 ** Returns          TRUE if success
604 **
605 *******************************************************************************/
rw_t4t_select_app(void)606 static bool rw_t4t_select_app(void) {
607   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
608   NFC_HDR* p_c_apdu;
609   uint8_t* p;
610 
611   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
612 
613   if (!p_c_apdu) {
614     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
615     return false;
616   }
617 
618   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
619   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
620 
621   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
622   UINT8_TO_BE_STREAM(p, T4T_CMD_SELECT_APP);
623   UINT16_TO_BE_STREAM(p, 0x0000);
624   UINT8_TO_BE_STREAM(p, 0x03); /* Lc: length of wrapped data */
625   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
626     UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
627   } else {
628     UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
629   }
630 
631   UINT8_TO_BE_STREAM(p, 0x00); /* Le */
632 
633   p_c_apdu->len = 9;
634 
635   if (!rw_t4t_send_to_lower(p_c_apdu)) {
636     return false;
637   }
638 
639   return true;
640 }
641 
642 /*******************************************************************************
643 **
644 ** Function         rw_t4t_create_ccfile
645 **
646 ** Description      create capability container file cmd to peer
647 **
648 ** Returns          TRUE if success
649 **
650 *******************************************************************************/
rw_t4t_create_ccfile(void)651 static bool rw_t4t_create_ccfile(void) {
652   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
653   NFC_HDR* p_c_apdu;
654   uint8_t* p;
655 
656   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
657 
658   if (!p_c_apdu) {
659     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
660     return false;
661   }
662 
663   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
664   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
665 
666   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
667   UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
668   UINT16_TO_BE_STREAM(p, 0x0000);
669   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
670     UINT8_TO_BE_STREAM(p, 0x09);    /* Lc: length of wrapped data */
671     UINT8_TO_BE_STREAM(p, 0x01);    /* EV1 CC file id             */
672     UINT16_TO_BE_STREAM(p, 0x03E1); /* ISO file id                */
673   } else {
674     UINT8_TO_BE_STREAM(p, 0x07); /* Lc: length of wrapped data */
675     UINT8_TO_BE_STREAM(p, 0x03); /* DESFire CC file id         */
676   }
677 
678   UINT8_TO_BE_STREAM(p, 0x00);      /* COMM settings              */
679   UINT16_TO_BE_STREAM(p, 0xEEEE);   /* Access rights              */
680   UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set file size              */
681   UINT8_TO_BE_STREAM(p, 0x00);      /* Le                         */
682 
683   p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
684 
685   if (!rw_t4t_send_to_lower(p_c_apdu)) {
686     return false;
687   }
688 
689   return true;
690 }
691 
692 /*******************************************************************************
693 **
694 ** Function         rw_t4t_create_ndef
695 **
696 ** Description      creates an ndef file cmd to peer
697 **
698 ** Returns          TRUE if success
699 **
700 *******************************************************************************/
rw_t4t_create_ndef(void)701 static bool rw_t4t_create_ndef(void) {
702   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
703   NFC_HDR* p_c_apdu;
704   uint8_t* p;
705 
706   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
707 
708   if (!p_c_apdu) {
709     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
710     return false;
711   }
712 
713   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
714   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
715 
716   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
717   UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
718   UINT16_TO_BE_STREAM(p, 0x0000);
719   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
720     UINT8_TO_BE_STREAM(p, 0x09);    /* Lc: length of wrapped data */
721     UINT8_TO_BE_STREAM(p, 0x02);    /* DESFEv1 NDEF file id       */
722     UINT16_TO_BE_STREAM(p, 0x04E1); /* ISO file id                */
723   } else {
724     UINT8_TO_BE_STREAM(p, 0x07);
725     UINT8_TO_BE_STREAM(p, 0x04); /* DESF4 NDEF file id        */
726   }
727 
728   UINT8_TO_BE_STREAM(p, 0x00);    /* COMM settings              */
729   UINT16_TO_BE_STREAM(p, 0xEEEE); /* Access rights              */
730   UINT16_TO_STREAM(p, p_t4t->card_size);
731   UINT8_TO_BE_STREAM(p, 0x00); /* Set card size              */
732   UINT8_TO_BE_STREAM(p, 0x00); /* Le                         */
733 
734   p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
735 
736   if (!rw_t4t_send_to_lower(p_c_apdu)) {
737     return false;
738   }
739 
740   return true;
741 }
742 
743 /*******************************************************************************
744 **
745 ** Function         rw_t4t_write_cc
746 **
747 ** Description      sends write cc file cmd to peer
748 **
749 ** Returns          TRUE if success
750 **
751 *******************************************************************************/
rw_t4t_write_cc(void)752 static bool rw_t4t_write_cc(void) {
753   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
754   NFC_HDR* p_c_apdu;
755   uint8_t* p;
756   uint8_t CCFileBytes[] = {0x00, 0x0F, 0x10, 0x00, 0x3B, 0x00, 0x34, 0x04,
757                            0x06, 0xE1, 0x04, 0x04, 0x00, 0x00, 0x00};
758 
759   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
760 
761   if (!p_c_apdu) {
762     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
763     return false;
764   }
765 
766   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
767   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
768 
769   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
770   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
771   UINT16_TO_BE_STREAM(p, 0x0000);
772   UINT8_TO_BE_STREAM(p, 0x16); /* Lc: length of wrapped data  */
773   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
774     CCFileBytes[2] = 0x20;
775     CCFileBytes[11] = p_t4t->card_size >> 8;
776     CCFileBytes[12] = (uint8_t)p_t4t->card_size;
777     UINT8_TO_BE_STREAM(p, 0x01); /* CC file id                  */
778   } else {
779     UINT8_TO_BE_STREAM(p, 0x03);
780   }
781 
782   UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset              */
783   UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set available length        */
784   ARRAY_TO_BE_STREAM(p, CCFileBytes, (int)sizeof(CCFileBytes));
785   UINT8_TO_BE_STREAM(p, 0x00); /* Le                         */
786 
787   p_c_apdu->len = 28;
788 
789   if (!rw_t4t_send_to_lower(p_c_apdu)) {
790     return false;
791   }
792 
793   return true;
794 }
795 
796 /*******************************************************************************
797 **
798 ** Function         rw_t4t_write_ndef
799 **
800 ** Description      sends write ndef file cmd to peer
801 **
802 ** Returns          TRUE if success
803 **
804 *******************************************************************************/
rw_t4t_write_ndef(void)805 static bool rw_t4t_write_ndef(void) {
806   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
807   NFC_HDR* p_c_apdu;
808   uint8_t* p;
809 
810   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
811 
812   if (!p_c_apdu) {
813     LOG(ERROR) << StringPrintf("Cannot allocate buffer");
814     return false;
815   }
816 
817   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
818   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
819 
820   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
821   UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
822   UINT16_TO_BE_STREAM(p, 0x0000);
823   UINT8_TO_BE_STREAM(p, 0x09); /* Lc: length of wrapped data  */
824   if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
825     UINT8_TO_BE_STREAM(p, 0x02); /* DESFEv1 Ndef file id        */
826   } else {
827     UINT8_TO_BE_STREAM(p, 0x04);
828   }
829 
830   UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset              */
831   UINT24_TO_BE_STREAM(p, 0x020000); /* Set available length        */
832   UINT16_TO_BE_STREAM(p, 0x0000);   /* Ndef file bytes             */
833   UINT8_TO_BE_STREAM(p, 0x00);      /* Le                          */
834 
835   p_c_apdu->len = 15;
836 
837   if (!rw_t4t_send_to_lower(p_c_apdu)) {
838     return false;
839   }
840 
841   return true;
842 }
843 
844 /*******************************************************************************
845 **
846 ** Function         rw_t4t_select_file
847 **
848 ** Description      Send Select Command (by File ID) to peer
849 **
850 ** Returns          TRUE if success
851 **
852 *******************************************************************************/
rw_t4t_select_file(uint16_t file_id)853 static bool rw_t4t_select_file(uint16_t file_id) {
854   NFC_HDR* p_c_apdu;
855   uint8_t* p;
856 
857   LOG(VERBOSE) << StringPrintf("%s - File ID:0x%04X", __func__, file_id);
858 
859   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
860 
861   if (!p_c_apdu) {
862     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
863     return false;
864   }
865 
866   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
867   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
868 
869   UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
870   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
871   UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_FILE_ID);
872 
873   /* if current version mapping is V2.0 */
874   if ((rw_cb.tcb.t4t.version == T4T_VERSION_2_0) ||
875       (rw_cb.tcb.t4t.version == T4T_VERSION_3_0)) {
876     UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
877   } else /* version 1.0 */
878   {
879     UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
880   }
881 
882   UINT8_TO_BE_STREAM(p, T4T_FILE_ID_SIZE);
883   UINT16_TO_BE_STREAM(p, file_id);
884 
885   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;
886 
887   if (!rw_t4t_send_to_lower(p_c_apdu)) {
888     return false;
889   }
890 
891   return true;
892 }
893 
894 /*******************************************************************************
895 **
896 ** Function         rw_t4t_read_file
897 **
898 ** Description      Send ReadBinary Command to peer
899 **
900 ** Returns          TRUE if success
901 **
902 *******************************************************************************/
rw_t4t_read_file(uint32_t offset,uint32_t length,bool is_continue)903 static bool rw_t4t_read_file(uint32_t offset, uint32_t length,
904                              bool is_continue) {
905   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
906   NFC_HDR* p_c_apdu;
907   uint8_t* p;
908   uint32_t tmp_offset;
909 
910   LOG(VERBOSE) << StringPrintf("%s - offset:%d, length:%d, is_continue:%d, ",
911                              __func__, offset, length, is_continue);
912 
913   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
914 
915   if (!p_c_apdu) {
916     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
917     return false;
918   }
919 
920   /* if this is the first reading */
921   if (is_continue == false) {
922     /* initialise starting offset and total length */
923     /* these will be updated when receiving response */
924     p_t4t->rw_offset = offset;
925     p_t4t->rw_length = length;
926   }
927 
928   /* adjust reading length if payload is bigger than max size per single command
929    */
930   if (length > p_t4t->max_read_size) {
931     length = (uint32_t)(p_t4t->max_read_size);
932   }
933 
934   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
935   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
936 
937   UINT8_TO_BE_STREAM(p, (T4T_CMD_CLASS | rw_cb.tcb.t4t.channel));
938   if ((p_t4t->rw_offset + p_t4t->rw_length) > 0x7FFF) {
939     /* ReadBinary with ODO must be used */
940     if (p_t4t->cc_file.version >= T4T_VERSION_3_0) {
941       /* MV 3.0 tag */
942       LOG(VERBOSE) << StringPrintf(
943           "%s - Read above 0x7FFF address offset detected", __func__);
944 
945       p_c_apdu->len = T4T_CMD_MIN_EXT_HDR_SIZE;
946 
947       UINT8_TO_BE_STREAM(p, T4T_CMD_INS_READ_BINARY_ODO);
948       /* P1 P2 field */
949       UINT16_TO_BE_STREAM(p, 0x0000);
950       /* Lc field */
951       if (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING) {
952         /* Coded over three bytes */
953         UINT16_TO_BE_STREAM(p, 0x0000);
954         UINT8_TO_BE_STREAM(p, 0x05);
955         p_c_apdu->len += 3;
956       } else {
957         /* Coded over 1 byte */
958         UINT8_TO_BE_STREAM(p, 0x05);
959         p_c_apdu->len += 1;
960       }
961       p_t4t->intl_flags |= RW_T4T_DDO_LC_FIELD_CODING;
962 
963       /* Data field containing address offset */
964       UINT16_TO_BE_STREAM(p, 0x5403);
965       tmp_offset = offset;
966       tmp_offset >>= 16;
967       UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
968       tmp_offset = offset;
969       tmp_offset >>= 8;
970       UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
971       tmp_offset = offset;
972       UINT8_TO_BE_STREAM(p, ((uint8_t)tmp_offset));
973 
974       /* Le field */
975       if (length < p_t4t->max_read_size) {
976         /* For the last R-APDU, must consider the DDO '53h' tag and data length
977          * size in the response. As difficult to know which coding will be used
978          * for BER-TLV, safer to request the remaining maximum number of bytes
979          * the tag can send */
980         length = 0x0000;
981       }
982       if (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING) {
983         /* If Lc is coded over 3 bytes, Le is coded over 2 bytes */
984         p_c_apdu->len += 2;
985         UINT16_TO_BE_STREAM(p, length);
986       } else {
987         /* Coded over 1 byte */
988         p_c_apdu->len += 1;
989         UINT8_TO_BE_STREAM(p, length);
990       }
991     } else {
992       LOG(ERROR) << StringPrintf("%s - Cannot read above 0x7FFF for MV2.0",
993                                  __func__);
994       GKI_freebuf(p_c_apdu);
995       return false;
996     }
997   } else {
998     /* MV 2.0 tag or MV 3.0 tag read below 32kB */
999     LOG(VERBOSE) << StringPrintf("%s - Read below 0x8000 address offset detected",
1000                                __func__);
1001 
1002     UINT8_TO_BE_STREAM(p, T4T_CMD_INS_READ_BINARY);
1003     /* Lc and Data fields absent */
1004     UINT16_TO_BE_STREAM(p, offset);
1005     if (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING) {
1006       /* Coded over three bytes with first one null */
1007       p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 3; /* adding Le */
1008       UINT8_TO_BE_STREAM(p, 0x00);
1009       UINT16_TO_BE_STREAM(p, length); /* Le */
1010     } else {
1011       /* If MLe=256 bytes, using UINT8_TO_BE_STREAM casts the length
1012        * to Le=0x00 which is accepted by the specifications but not
1013        * by all tags in the field. Force Le to 255 bytes to read the
1014        * remaining bytes in two times
1015        */
1016       if (length == (T4T_MAX_LENGTH_LE + 1)) {
1017         length = T4T_MAX_LENGTH_LE;
1018       }
1019       p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */
1020       UINT8_TO_BE_STREAM(p, length);            /* Le */
1021     }
1022   }
1023 
1024   if (!rw_t4t_send_to_lower(p_c_apdu)) {
1025     return false;
1026   }
1027 
1028   return true;
1029 }
1030 
1031 /*******************************************************************************
1032 **
1033 ** Function         rw_t4t_update_nlen
1034 **
1035 ** Description      Send UpdateBinary Command to update NLEN to peer
1036 **
1037 ** Returns          TRUE if success
1038 **
1039 *******************************************************************************/
rw_t4t_update_nlen(uint32_t ndef_len)1040 static bool rw_t4t_update_nlen(uint32_t ndef_len) {
1041   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1042   NFC_HDR* p_c_apdu;
1043   uint8_t* p;
1044 
1045   LOG(VERBOSE) << StringPrintf("%s - NLEN:%d", __func__, ndef_len);
1046 
1047   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1048 
1049   if (!p_c_apdu) {
1050     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
1051     return false;
1052   }
1053 
1054   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1055   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
1056 
1057   UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
1058   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
1059   UINT16_TO_BE_STREAM(p, 0x0000); /* offset for NLEN */
1060   UINT8_TO_BE_STREAM(p, p_t4t->cc_file.ndef_fc.nlen_size);
1061   if (p_t4t->cc_file.ndef_fc.nlen_size == T4T_FILE_LENGTH_SIZE) {
1062     UINT16_TO_BE_STREAM(p, ndef_len);
1063   } else {
1064     UINT32_TO_BE_STREAM(p, ndef_len);
1065   }
1066 
1067   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + p_t4t->cc_file.ndef_fc.nlen_size;
1068 
1069   if (!rw_t4t_send_to_lower(p_c_apdu)) {
1070     return false;
1071   }
1072 
1073   return true;
1074 }
1075 
1076 /*******************************************************************************
1077 **
1078 ** Function         rw_t4t_update_file
1079 **
1080 ** Description      Send UpdateBinary Command to peer
1081 **
1082 ** Returns          TRUE if success
1083 **
1084 *******************************************************************************/
rw_t4t_update_file(void)1085 static bool rw_t4t_update_file(void) {
1086   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1087   NFC_HDR* p_c_apdu;
1088   uint8_t* p;
1089   uint32_t length;
1090 
1091   LOG(VERBOSE) << StringPrintf("%s - rw_offset:%d, rw_length:%d", __func__,
1092                              p_t4t->rw_offset, p_t4t->rw_length);
1093 
1094   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1095 
1096   if (!p_c_apdu) {
1097     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
1098     return false;
1099   }
1100 
1101   /* try to send all of remaining data */
1102   length = p_t4t->rw_length;
1103 
1104   if (length == 0) {
1105     LOG(ERROR) << StringPrintf("%s - Length to write can not be null",
1106                                __func__);
1107     GKI_freebuf(p_c_apdu);
1108     return false;
1109   }
1110 
1111   /* adjust updating length if payload is bigger than max size per single
1112    * command */
1113   if (length > p_t4t->max_update_size) {
1114     length = (uint32_t)(p_t4t->max_update_size);
1115   }
1116 
1117   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1118   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
1119 
1120   if ((p_t4t->rw_offset + p_t4t->rw_length) > 0x7FFF) {
1121     /* UpdateBinary with ODO and DDO */
1122     if (p_t4t->cc_file.version >= T4T_VERSION_3_0) {
1123       /* MV 3.0 tag */
1124       LOG(VERBOSE) << StringPrintf(
1125           "%s - MV 3.0 detected, update NDEF Message size > 0x7FFF", __func__);
1126 
1127       return rw_t4t_set_ber_tlv(p_c_apdu, p, length);
1128 
1129     } else {
1130       LOG(ERROR) << StringPrintf("%s - Cannot write above 0x7FFF for MV2.0",
1131                                  __func__);
1132       GKI_freebuf(p_c_apdu);
1133       return false;
1134     }
1135   } else {
1136     /* MV 2.0 or MV 3.0 tag */
1137     /* ReadBinary with Standard Data structure used */
1138     LOG(VERBOSE) << StringPrintf(
1139         "%s - NDEF Message to write < 0x8000, MV2.0 or MV3.0 tag", __func__);
1140 
1141     UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
1142     UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
1143     UINT16_TO_BE_STREAM(p, p_t4t->rw_offset);
1144 
1145     /* Lc field encoded using Short Field Coding */
1146     if (length > T4T_MAX_LENGTH_LC) {
1147       /* Write a max of 255 bytes,
1148        * as Lc=00 is reserved for Extended Field coding */
1149       length = T4T_MAX_LENGTH_LC;
1150     }
1151     UINT8_TO_BE_STREAM(p, length);
1152 
1153     memcpy(p, p_t4t->p_update_data, length);
1154 
1155     p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;
1156 
1157     if (!rw_t4t_send_to_lower(p_c_apdu)) {
1158       return false;
1159     }
1160 
1161     /* adjust offset, length and pointer for remaining data */
1162     p_t4t->rw_offset += length;
1163     p_t4t->rw_length -= length;
1164     p_t4t->p_update_data += length;
1165   }
1166 
1167   return true;
1168 }
1169 
1170 /*******************************************************************************
1171 **
1172 ** Function         rw_t4t_update_cc_to_readonly
1173 **
1174 ** Description      Send UpdateBinary Command for changing Write access
1175 **
1176 ** Returns          TRUE if success
1177 **
1178 *******************************************************************************/
rw_t4t_update_cc_to_readonly(void)1179 static bool rw_t4t_update_cc_to_readonly(void) {
1180   NFC_HDR* p_c_apdu;
1181   uint8_t* p;
1182 
1183   LOG(VERBOSE) << StringPrintf("%s - Remove Write access from CC", __func__);
1184 
1185   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1186 
1187   if (!p_c_apdu) {
1188     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
1189     return false;
1190   }
1191 
1192   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1193   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
1194 
1195   /* Add Command Header */
1196   UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
1197   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
1198   UINT16_TO_BE_STREAM(
1199       p, (T4T_FC_TLV_OFFSET_IN_CC +
1200           T4T_FC_WRITE_ACCESS_OFFSET_IN_TLV)); /* Offset for Read Write access
1201                                                   byte of CC */
1202   UINT8_TO_BE_STREAM(
1203       p, 1); /* Length of write access field in cc interms of bytes */
1204 
1205   /* Remove Write access */
1206   UINT8_TO_BE_STREAM(p, T4T_FC_NO_WRITE_ACCESS);
1207 
1208   p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + 1;
1209 
1210   if (!rw_t4t_send_to_lower(p_c_apdu)) {
1211     return false;
1212   }
1213 
1214   return true;
1215 }
1216 
1217 /*******************************************************************************
1218 **
1219 ** Function         rw_t4t_select_application
1220 **
1221 ** Description      Select Application
1222 **
1223 **                  NDEF Tag Application Select - C-APDU
1224 **
1225 **                        CLA INS P1 P2 Lc Data(AID)      Le
1226 **                  V1.0: 00  A4  04 00 07 D2760000850100 -
1227 **                  V2.0: 00  A4  04 00 07 D2760000850101 00
1228 **                  V3.0: 00  A4  04 00 07 D2760000850101 00
1229 **
1230 ** Returns          TRUE if success
1231 **
1232 *******************************************************************************/
rw_t4t_select_application(uint8_t version)1233 static bool rw_t4t_select_application(uint8_t version) {
1234   NFC_HDR* p_c_apdu;
1235   uint8_t* p;
1236 
1237   LOG(VERBOSE) << StringPrintf("%s - version:0x%X", __func__, version);
1238 
1239   p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
1240 
1241   if (!p_c_apdu) {
1242     LOG(ERROR) << StringPrintf("%s - Cannot allocate buffer", __func__);
1243     return false;
1244   }
1245 
1246   p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1247   p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
1248 
1249   UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
1250   UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
1251   UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_NAME);
1252   UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
1253 
1254   if (version == T4T_VERSION_1_0) /* this is for V1.0 */
1255   {
1256     UINT8_TO_BE_STREAM(p, T4T_V10_NDEF_TAG_AID_LEN);
1257 
1258     memcpy(p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN);
1259 
1260     p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN;
1261   } else if ((version == T4T_VERSION_2_0) || /* this is for V2.0 */
1262              (version == T4T_VERSION_3_0))   /* this is for V3.0 */
1263   {
1264     UINT8_TO_BE_STREAM(p, T4T_V20_NDEF_TAG_AID_LEN);
1265 
1266     memcpy(p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN);
1267     p += T4T_V20_NDEF_TAG_AID_LEN;
1268 
1269     UINT8_TO_BE_STREAM(p, 0x00); /* Le set to 0x00 */
1270 
1271     p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1;
1272   } else {
1273     GKI_freebuf(p_c_apdu);
1274     return false;
1275   }
1276 
1277   if (!rw_t4t_send_to_lower(p_c_apdu)) {
1278     return false;
1279   }
1280 
1281   return true;
1282 }
1283 
1284 /*******************************************************************************
1285 **
1286 ** Function         rw_t4t_validate_cc_file
1287 **
1288 ** Description      Validate CC file and mandatory NDEF TLV
1289 **
1290 ** Returns          TRUE if success
1291 **
1292 *******************************************************************************/
rw_t4t_validate_cc_file(void)1293 static bool rw_t4t_validate_cc_file(void) {
1294   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1295 
1296   LOG(VERBOSE) << __func__;
1297 
1298   if (p_t4t->cc_file.cclen < T4T_CC_FILE_MIN_LEN) {
1299     LOG(ERROR) << StringPrintf("%s - CCLEN (%d) is too short", __func__,
1300                                p_t4t->cc_file.cclen);
1301     return false;
1302   }
1303 
1304   if (T4T_GET_MAJOR_VERSION(p_t4t->cc_file.version) >
1305       T4T_GET_MAJOR_VERSION(p_t4t->version)) {
1306     LOG(ERROR) << StringPrintf(
1307         "%s - Peer version (0x%02X) mismatched to ours "
1308         "(0x%02X)",
1309         __func__, p_t4t->cc_file.version, p_t4t->version);
1310 
1311     return false;
1312   }
1313 
1314   if (p_t4t->cc_file.max_le < 0x000F) {
1315     LOG(ERROR) << StringPrintf("%s - MaxLe (%d) is too small", __func__,
1316                                p_t4t->cc_file.max_le);
1317     return false;
1318   }
1319 
1320   if (p_t4t->cc_file.max_lc < 0x0001 ||
1321       ((p_t4t->cc_file.max_lc < 0x000D) && appl_dta_mode_flag)) {
1322     LOG(ERROR) << StringPrintf("%s - MaxLc (%d) is too small", __func__,
1323                                p_t4t->cc_file.max_lc);
1324     return false;
1325   }
1326 
1327   if ((p_t4t->cc_file.ndef_fc.file_id == T4T_CC_FILE_ID) ||
1328       (p_t4t->cc_file.ndef_fc.file_id == 0xE102) ||
1329       ((p_t4t->cc_file.ndef_fc.file_id == 0x0000) &&
1330        ((p_t4t->cc_file.version == 0x20) ||
1331         (p_t4t->cc_file.version == 0x30))) ||
1332       (p_t4t->cc_file.ndef_fc.file_id == 0x3F00) ||
1333       (p_t4t->cc_file.ndef_fc.file_id == 0x3FFF) ||
1334       (p_t4t->cc_file.ndef_fc.file_id == 0xFFFF)) {
1335     LOG(ERROR) << StringPrintf("%s - File ID (0x%04X) is invalid", __func__,
1336                                p_t4t->cc_file.ndef_fc.file_id);
1337     return false;
1338   }
1339 
1340   if (((p_t4t->cc_file.version == 0x20) &&
1341        ((p_t4t->cc_file.ndef_fc.max_file_size < 0x0005) ||
1342         (p_t4t->cc_file.ndef_fc.max_file_size > 0x7FFF))) ||
1343       ((p_t4t->cc_file.version == 0x30) &&
1344        ((p_t4t->cc_file.ndef_fc.max_file_size < 0x00000007) ||
1345         (p_t4t->cc_file.ndef_fc.max_file_size == 0xFFFFFFFF)))) {
1346     LOG(ERROR) << StringPrintf("%s - max_file_size (%d) is reserved", __func__,
1347                                p_t4t->cc_file.ndef_fc.max_file_size);
1348     return false;
1349   }
1350 
1351   if (((p_t4t->cc_file.ndef_fc.read_access > T4T_FC_READ_ACCESS) &&
1352        (p_t4t->cc_file.ndef_fc.read_access < T4T_FC_READ_ACCESS_PROP_START)) ||
1353       (p_t4t->cc_file.ndef_fc.read_access == T4T_FC_NO_READ_ACCESS)) {
1354     LOG(ERROR) << StringPrintf("%s - Read Access (0x%02X) is invalid", __func__,
1355                                p_t4t->cc_file.ndef_fc.read_access);
1356     return false;
1357   }
1358 
1359   if (((p_t4t->cc_file.ndef_fc.write_access > T4T_FC_WRITE_ACCESS) &&
1360        (p_t4t->cc_file.ndef_fc.write_access <
1361         T4T_FC_WRITE_ACCESS_PROP_START))) {
1362     LOG(ERROR) << StringPrintf("%s - Write Access (0x%02X) is invalid",
1363                                __func__, p_t4t->cc_file.ndef_fc.write_access);
1364     return false;
1365   }
1366 
1367   return true;
1368 }
1369 
1370 /*******************************************************************************
1371 **
1372 ** Function         rw_t4t_handle_error
1373 **
1374 ** Description      notify error to application and clean up
1375 **
1376 ** Returns          none
1377 **
1378 *******************************************************************************/
rw_t4t_handle_error(tNFC_STATUS status,uint8_t sw1,uint8_t sw2)1379 static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2) {
1380   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1381   tRW_DATA rw_data;
1382   tRW_EVENT event;
1383 
1384   LOG(VERBOSE) << StringPrintf(
1385       "%s - status:0x%02X, sw1:0x%02X, sw2:0x%02X, "
1386       "state:0x%X",
1387       __func__, status, sw1, sw2, p_t4t->state);
1388 
1389   nfc_stop_quick_timer(&p_t4t->timer);
1390 
1391   if (rw_cb.p_cback) {
1392     rw_data.status = status;
1393 
1394     rw_data.t4t_sw.sw1 = sw1;
1395     rw_data.t4t_sw.sw2 = sw2;
1396     rw_data.ndef.cur_size = 0;
1397     rw_data.ndef.max_size = 0;
1398 
1399     switch (p_t4t->state) {
1400       case RW_T4T_STATE_DETECT_NDEF:
1401         rw_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1402         event = RW_T4T_NDEF_DETECT_EVT;
1403         break;
1404 
1405       case RW_T4T_STATE_READ_NDEF:
1406         event = RW_T4T_NDEF_READ_FAIL_EVT;
1407         break;
1408 
1409       case RW_T4T_STATE_UPDATE_NDEF:
1410         event = RW_T4T_NDEF_UPDATE_FAIL_EVT;
1411         break;
1412 
1413       case RW_T4T_STATE_PRESENCE_CHECK:
1414         event = RW_T4T_PRESENCE_CHECK_EVT;
1415         rw_data.status = NFC_STATUS_FAILED;
1416         break;
1417 
1418       case RW_T4T_STATE_SET_READ_ONLY:
1419         event = RW_T4T_SET_TO_RO_EVT;
1420         break;
1421 
1422       case RW_T4T_STATE_NDEF_FORMAT:
1423         event = RW_T4T_NDEF_FORMAT_CPLT_EVT;
1424         rw_data.status = NFC_STATUS_FAILED;
1425         break;
1426 
1427       default:
1428         event = RW_T4T_MAX_EVT;
1429         break;
1430     }
1431 
1432     p_t4t->state = RW_T4T_STATE_IDLE;
1433 
1434     if (event != RW_T4T_MAX_EVT) {
1435       (*(rw_cb.p_cback))(event, &rw_data);
1436     }
1437   } else {
1438     p_t4t->state = RW_T4T_STATE_IDLE;
1439   }
1440 }
1441 
1442 /*******************************************************************************
1443 **
1444 ** Function         rw_t4t_sm_ndef_format
1445 **
1446 ** Description      State machine for NDEF format procedure
1447 **
1448 ** Returns          none
1449 **
1450 *******************************************************************************/
rw_t4t_sm_ndef_format(NFC_HDR * p_r_apdu)1451 static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu) {
1452   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1453   uint8_t* p;
1454   uint16_t status_words;
1455   tRW_DATA rw_data;
1456 
1457   LOG(VERBOSE) << StringPrintf(
1458       "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1459       p_t4t->sub_state);
1460 
1461   /* get status words */
1462   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1463 
1464   switch (p_t4t->sub_state) {
1465     case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
1466       p += (p_r_apdu->len - 1);
1467       if (*(p) == T4T_ADDI_FRAME_RESP) {
1468         if (!rw_t4t_get_sw_version()) {
1469           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1470         } else {
1471           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION;
1472         }
1473       } else {
1474         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1475       }
1476       break;
1477 
1478     case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
1479       p += (p_r_apdu->len - 1);
1480       if (*(p) == T4T_ADDI_FRAME_RESP) {
1481         if (!rw_t4t_update_version_details(p_r_apdu)) {
1482           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1483         }
1484 
1485         if (!rw_t4t_get_uid_details()) {
1486           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1487         }
1488 
1489         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_UID;
1490       } else {
1491         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1492       }
1493       break;
1494 
1495     case RW_T4T_SUBSTATE_WAIT_GET_UID:
1496       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1497       BE_STREAM_TO_UINT16(status_words, p);
1498       if (status_words != 0x9100) {
1499         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1500       } else {
1501         if (!rw_t4t_create_app()) {
1502           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1503         } else {
1504           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_APP;
1505         }
1506       }
1507       break;
1508 
1509     case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
1510       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1511       BE_STREAM_TO_UINT16(status_words, p);
1512       if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1513       {
1514         status_words = 0x9100;
1515       }
1516 
1517       if (status_words != 0x9100) {
1518         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1519       } else {
1520         if (!rw_t4t_select_app()) {
1521           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1522         } else {
1523           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
1524         }
1525       }
1526       break;
1527 
1528     case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
1529       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1530       BE_STREAM_TO_UINT16(status_words, p);
1531       if (status_words != 0x9100) {
1532         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1533       } else {
1534         if (!rw_t4t_create_ccfile()) {
1535           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1536         } else {
1537           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_CC;
1538         }
1539       }
1540       break;
1541 
1542     case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
1543       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1544       BE_STREAM_TO_UINT16(status_words, p);
1545       if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1546       {
1547         status_words = 0x9100;
1548       }
1549 
1550       if (status_words != 0x9100) {
1551         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1552       } else {
1553         if (!rw_t4t_create_ndef()) {
1554           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1555         } else {
1556           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_NDEF;
1557         }
1558       }
1559       break;
1560 
1561     case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
1562       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1563       BE_STREAM_TO_UINT16(status_words, p);
1564       if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1565       {
1566         status_words = 0x9100;
1567       }
1568 
1569       if (status_words != 0x9100) {
1570         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1571       } else {
1572         if (!rw_t4t_write_cc()) {
1573           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1574         } else {
1575           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_CC;
1576         }
1577       }
1578       break;
1579 
1580     case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
1581       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1582       BE_STREAM_TO_UINT16(status_words, p);
1583       if (status_words != 0x9100) {
1584         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1585       } else {
1586         if (!rw_t4t_write_ndef()) {
1587           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1588         } else {
1589           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_NDEF;
1590         }
1591       }
1592       break;
1593 
1594     case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
1595       p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1596       BE_STREAM_TO_UINT16(status_words, p);
1597       if (status_words != 0x9100) {
1598         rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1599       } else {
1600         p_t4t->state = RW_T4T_STATE_IDLE;
1601         if (rw_cb.p_cback) {
1602           rw_data.ndef.status = NFC_STATUS_OK;
1603           rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
1604           rw_data.ndef.max_size = p_t4t->card_size;
1605           rw_data.ndef.cur_size = 0x00;
1606 
1607           (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
1608 
1609           LOG(VERBOSE) << StringPrintf("Sent RW_T4T_NDEF_FORMAT_CPLT_EVT");
1610         }
1611       }
1612       break;
1613 
1614     default:
1615       LOG(ERROR) << StringPrintf("unknown sub_state=%d", p_t4t->sub_state);
1616       rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1617       break;
1618   }
1619 }
1620 
1621 /*******************************************************************************
1622 **
1623 ** Function         rw_t4t_sm_detect_ndef
1624 **
1625 ** Description      State machine for NDEF detection procedure
1626 **
1627 ** Returns          none
1628 **
1629 *******************************************************************************/
rw_t4t_sm_detect_ndef(NFC_HDR * p_r_apdu)1630 static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu) {
1631   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1632   uint8_t *p, type, length;
1633   uint32_t nlen;
1634   uint32_t cc_file_offset = 0x00;
1635   uint16_t status_words;
1636   uint8_t cc_file_rsp_len = T4T_CC_FILE_MIN_LEN;
1637   tRW_DATA rw_data;
1638 
1639   LOG(VERBOSE) << StringPrintf(
1640       "%s - sub_state:%s (%d)", __func__,
1641       rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(), p_t4t->sub_state);
1642 
1643   /* get status words */
1644   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1645   p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1646   BE_STREAM_TO_UINT16(status_words, p);
1647 
1648   if (status_words != T4T_RSP_CMD_CMPLTED) {
1649     /* try V1.0 after failing of V2.0 or V3.0 */
1650     if ((p_t4t->sub_state == RW_T4T_SUBSTATE_WAIT_SELECT_APP) &&
1651         ((p_t4t->version == T4T_VERSION_2_0) ||
1652          (p_t4t->version == T4T_VERSION_3_0))) {
1653       p_t4t->version = T4T_VERSION_1_0;
1654 
1655       LOG(VERBOSE) << StringPrintf("%s - retry with version=0x%02X", __func__,
1656                                  p_t4t->version);
1657 
1658       if (!rw_t4t_select_application(T4T_VERSION_1_0)) {
1659         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1660       }
1661       return;
1662     }
1663 
1664     p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1665     rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1666     return;
1667   }
1668 
1669   switch (p_t4t->sub_state) {
1670     case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
1671 
1672       /* NDEF Tag application has been selected then select CC file */
1673       if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
1674         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1675       } else {
1676         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
1677       }
1678       break;
1679 
1680     case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
1681 
1682       /* CC file has been selected then read mandatory part of CC file */
1683       cc_file_offset = 0x00;
1684       if (!rw_t4t_read_file(cc_file_offset, cc_file_rsp_len, false)) {
1685         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1686       } else {
1687         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CC_FILE;
1688       }
1689       break;
1690 
1691     case RW_T4T_SUBSTATE_WAIT_CC_FILE:
1692 
1693       /* CC file has been read then validate and select mandatory NDEF file */
1694       if (p_r_apdu->len >= cc_file_rsp_len + T4T_RSP_STATUS_WORDS_SIZE) {
1695         p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1696 
1697         BE_STREAM_TO_UINT16(p_t4t->cc_file.cclen, p);
1698         BE_STREAM_TO_UINT8(p_t4t->cc_file.version, p);
1699         BE_STREAM_TO_UINT16(p_t4t->cc_file.max_le, p);
1700         BE_STREAM_TO_UINT16(p_t4t->cc_file.max_lc, p);
1701 
1702         BE_STREAM_TO_UINT8(type, p);
1703         BE_STREAM_TO_UINT8(length, p);
1704 
1705         if ((type == T4T_NDEF_FILE_CONTROL_TYPE) &&
1706             (length == T4T_FILE_CONTROL_LENGTH)) {
1707           BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.file_id, p);
1708           BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.max_file_size, p);
1709           BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.read_access, p);
1710           BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.write_access, p);
1711 
1712           LOG(VERBOSE) << StringPrintf("%s - Capability Container (CC) file",
1713                                      __func__);
1714           LOG(VERBOSE) << StringPrintf("%s -   CCLEN:  0x%04X", __func__,
1715                                      p_t4t->cc_file.cclen);
1716           LOG(VERBOSE) << StringPrintf("%s -   Version:0x%02X", __func__,
1717                                      p_t4t->cc_file.version);
1718           LOG(VERBOSE) << StringPrintf("%s -  MaxLe:  0x%04X", __func__,
1719                                      p_t4t->cc_file.max_le);
1720           LOG(VERBOSE) << StringPrintf("%s -   MaxLc:  0x%04X", __func__,
1721                                      p_t4t->cc_file.max_lc);
1722           LOG(VERBOSE) << StringPrintf("%s -  NDEF File Control TLV", __func__);
1723           LOG(VERBOSE) << StringPrintf("%s -    FileID:      0x%04X", __func__,
1724                                      p_t4t->cc_file.ndef_fc.file_id);
1725           LOG(VERBOSE) << StringPrintf("%s -    MaxFileSize: 0x%04X", __func__,
1726                                      p_t4t->cc_file.ndef_fc.max_file_size);
1727           LOG(VERBOSE) << StringPrintf("%s -     ReadAccess:  0x%02X", __func__,
1728                                      p_t4t->cc_file.ndef_fc.read_access);
1729           LOG(VERBOSE) << StringPrintf("%s -    WriteAccess: 0x%02X", __func__,
1730                                      p_t4t->cc_file.ndef_fc.write_access);
1731 
1732           if (rw_t4t_validate_cc_file()) {
1733             if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
1734               rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1735             } else {
1736               p_t4t->cc_file.ndef_fc.nlen_size = T4T_FILE_LENGTH_SIZE;
1737               p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
1738             }
1739             break;
1740           }
1741         } else if ((type == T4T_ENDEF_FILE_CONTROL_TYPE) &&
1742                    (length == T4T_ENDEF_FILE_CONTROL_LENGTH)) {
1743           LOG(VERBOSE) << StringPrintf("%s - Capability Container (CC) file",
1744                                      __func__);
1745           LOG(VERBOSE) << StringPrintf("%s -   CCLEN:  0x%04X", __func__,
1746                                      p_t4t->cc_file.cclen);
1747           LOG(VERBOSE) << StringPrintf("%s -   Version:0x%02X", __func__,
1748                                      p_t4t->cc_file.version);
1749           LOG(VERBOSE) << StringPrintf("%s -   MaxLe:  0x%04X", __func__,
1750                                      p_t4t->cc_file.max_le);
1751           LOG(VERBOSE) << StringPrintf("%s -   MaxLc:  0x%04X", __func__,
1752                                      p_t4t->cc_file.max_lc);
1753 
1754           cc_file_offset = T4T_ENDEF_FC_V_FIELD_OFFSET;
1755           cc_file_rsp_len = T4T_ENDEF_FILE_CONTROL_TLV_SIZE - 2;
1756 
1757           /* CC file has been selected then now read from control TLV area part
1758            * of CC file */
1759           /* assume ENDEF Ctrl TLV is the first one */
1760           /* read again the TLV as 2 bytes missing */
1761           if (!rw_t4t_read_file(cc_file_offset, cc_file_rsp_len, false)) {
1762             rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1763           } else {
1764             p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_ENDEF_FILE_CTRL_TLV;
1765           }
1766           break;
1767         }
1768       }
1769 
1770       /* invalid response or CC file */
1771       p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1772       rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1773       break;
1774 
1775     case RW_T4T_SUBSTATE_WAIT_ENDEF_FILE_CTRL_TLV:
1776 
1777       if (p_r_apdu->len >=
1778           T4T_ENDEF_FILE_CONTROL_LENGTH + T4T_RSP_STATUS_WORDS_SIZE) {
1779         p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1780 
1781         BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.file_id, p);
1782         BE_STREAM_TO_UINT32(p_t4t->cc_file.ndef_fc.max_file_size, p);
1783         BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.read_access, p);
1784         BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.write_access, p);
1785 
1786         LOG(VERBOSE) << StringPrintf("%s -  ENDEF File Control TLV", __func__);
1787         LOG(VERBOSE) << StringPrintf("%s -    FileID:      0x%04X", __func__,
1788                                    p_t4t->cc_file.ndef_fc.file_id);
1789         LOG(VERBOSE) << StringPrintf("%s -    MaxFileSize: 0x%08X", __func__,
1790                                    p_t4t->cc_file.ndef_fc.max_file_size);
1791         LOG(VERBOSE) << StringPrintf("%s -    ReadAccess:  0x%02X", __func__,
1792                                    p_t4t->cc_file.ndef_fc.read_access);
1793         LOG(VERBOSE) << StringPrintf("%s -    WriteAccess: 0x%02X", __func__,
1794                                    p_t4t->cc_file.ndef_fc.write_access);
1795 
1796         if (rw_t4t_validate_cc_file()) {
1797           if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
1798             rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1799           } else {
1800             p_t4t->cc_file.ndef_fc.nlen_size = T4T_EFILE_LENGTH_SIZE;
1801             p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
1802           }
1803           break;
1804         }
1805       }
1806 
1807       /* invalid response or CC file */
1808       p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1809       rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1810       break;
1811 
1812     case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
1813 
1814       /* NDEF file has been selected then read the first 2 bytes (NLEN) */
1815       if (!rw_t4t_read_file(0, p_t4t->cc_file.ndef_fc.nlen_size, false)) {
1816         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1817       } else {
1818         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_NLEN;
1819       }
1820       break;
1821 
1822     case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
1823 
1824       /* NLEN has been read then report upper layer */
1825       if (p_r_apdu->len ==
1826           p_t4t->cc_file.ndef_fc.nlen_size + T4T_RSP_STATUS_WORDS_SIZE) {
1827         /* get length of NDEF */
1828         p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1829         if (p_t4t->cc_file.ndef_fc.nlen_size == T4T_FILE_LENGTH_SIZE) {
1830           BE_STREAM_TO_UINT16(nlen, p);
1831         } else {
1832           BE_STREAM_TO_UINT32(nlen, p);
1833         }
1834 
1835         if (nlen <= p_t4t->cc_file.ndef_fc.max_file_size -
1836                         p_t4t->cc_file.ndef_fc.nlen_size) {
1837           p_t4t->ndef_status = RW_T4T_NDEF_STATUS_NDEF_DETECTED;
1838 
1839           if (p_t4t->cc_file.ndef_fc.write_access == T4T_FC_NO_WRITE_ACCESS) {
1840             p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
1841           }
1842 
1843           /* Get max bytes to read per command */
1844           if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ) {
1845             p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
1846           } else {
1847             p_t4t->max_read_size = p_t4t->cc_file.max_le;
1848           }
1849 
1850           LOG(VERBOSE) << StringPrintf("%s -    max_read_size:      0x%04X",
1851                                      __func__, p_t4t->max_read_size);
1852 
1853           /* Le: valid range is 0x0001 to 0xFFFF */
1854           if (p_t4t->max_read_size > T4T_MAX_LENGTH_LE + 1) {
1855             /* Extended Field Coding supported by the tag */
1856             p_t4t->intl_flags |= RW_T4T_EXT_FIELD_CODING;
1857           }
1858 
1859           /* Get max bytes to update per command */
1860           if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE) {
1861             p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
1862           } else {
1863             p_t4t->max_update_size = p_t4t->cc_file.max_lc;
1864           }
1865 
1866           /* Lc: valid range is 0x0001 to 0xFFFF */
1867           if (p_t4t->max_update_size > T4T_MAX_LENGTH_LC) {
1868             /* Extended Field Coding supported by the tag */
1869             p_t4t->intl_flags |= RW_T4T_EXT_FIELD_CODING;
1870           }
1871 
1872           p_t4t->ndef_length = nlen;
1873           p_t4t->state = RW_T4T_STATE_IDLE;
1874 
1875           if (rw_cb.p_cback) {
1876             rw_data.ndef.status = NFC_STATUS_OK;
1877             rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
1878             rw_data.ndef.max_size =
1879                 (uint32_t)(p_t4t->cc_file.ndef_fc.max_file_size -
1880                            (uint16_t)p_t4t->cc_file.ndef_fc.nlen_size);
1881             rw_data.ndef.cur_size = nlen;
1882             rw_data.ndef.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
1883             if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) {
1884               rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
1885             }
1886 
1887             (*(rw_cb.p_cback))(RW_T4T_NDEF_DETECT_EVT, &rw_data);
1888 
1889             LOG(VERBOSE) << StringPrintf("%s - Sent RW_T4T_NDEF_DETECT_EVT",
1890                                        __func__);
1891           }
1892         } else {
1893           /* NLEN should be less than max file size */
1894           LOG(ERROR) << StringPrintf(
1895               "%s - NLEN (%d) + 2 must be <= max file "
1896               "size (%d)",
1897               __func__, nlen, p_t4t->cc_file.ndef_fc.max_file_size);
1898 
1899           p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1900           rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1901         }
1902       } else {
1903         /* response payload size should be T4T_(E)FILE_LENGTH_SIZE */
1904         LOG(ERROR) << StringPrintf(
1905             "%s - Length (%d) of R-APDU must be %d", __func__, p_r_apdu->len,
1906             p_t4t->cc_file.ndef_fc.nlen_size + T4T_RSP_STATUS_WORDS_SIZE);
1907 
1908         p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1909         rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1910       }
1911       break;
1912 
1913     default:
1914       LOG(ERROR) << StringPrintf("%s - unknown sub_state=%d", __func__,
1915                                  p_t4t->sub_state);
1916       rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1917       break;
1918   }
1919 }
1920 
1921 /*******************************************************************************
1922 **
1923 ** Function         rw_t4t_sm_read_ndef
1924 **
1925 ** Description      State machine for NDEF read procedure
1926 **
1927 ** Returns          none
1928 **
1929 *******************************************************************************/
rw_t4t_sm_read_ndef(NFC_HDR * p_r_apdu)1930 static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu) {
1931   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1932   uint8_t* p;
1933   uint16_t status_words;
1934   uint16_t r_apdu_len;
1935   tRW_DATA rw_data;
1936 
1937   if (p_r_apdu == nullptr) {
1938     LOG(ERROR) << StringPrintf("%s; p_r_apdu is null, exiting", __func__);
1939     return;
1940   }
1941   LOG(VERBOSE) << StringPrintf(
1942       "%s - sub_state:%s (%d)", __func__,
1943       rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(), p_t4t->sub_state);
1944 
1945   /* get status words */
1946   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1947   p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1948   BE_STREAM_TO_UINT16(status_words, p);
1949 
1950   if (status_words != T4T_RSP_CMD_CMPLTED) {
1951     rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1952     GKI_freebuf(p_r_apdu);
1953     return;
1954   }
1955 
1956   switch (p_t4t->sub_state) {
1957     case RW_T4T_SUBSTATE_WAIT_READ_RESP:
1958 
1959       /* Read partial or complete data */
1960       p_r_apdu->len -= T4T_RSP_STATUS_WORDS_SIZE;
1961 
1962       p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1963       if (p_t4t->intl_flags & RW_T4T_DDO_LC_FIELD_CODING) {
1964         if (*p == 0x53) {
1965           /* ReadBinary command with ODO */
1966           if (*(p + 1) <= 0x7F) {
1967             p_r_apdu->len -= 2;
1968             p_r_apdu->offset += 2;
1969             /* Content read length coded over 1 byte in 1st byte
1970              * of BER-TLV length field */
1971             LOG(VERBOSE) << StringPrintf(
1972                 "%s - Content read length expected: 0x%02X, returned: 0x%02X",
1973                 __func__, *(p + 1), p_r_apdu->len);
1974             if (*(p + 1) == p_r_apdu->len) {
1975               if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length)) {
1976                 p_t4t->rw_length -= p_r_apdu->len;
1977                 p_t4t->rw_offset += p_r_apdu->len;
1978               }
1979             } else {
1980               LOG(ERROR) << StringPrintf(
1981                   "%s - invalid payload length (%d), rw_length (%d)", __func__,
1982                   p_r_apdu->len, p_t4t->rw_length);
1983               rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1984               break;
1985             }
1986           } else if (*(p + 1) == 0x81) {
1987             if (*(p + 2) <= 0xFD) {
1988               p_r_apdu->len -= 3;
1989               p_r_apdu->offset += 3;
1990               /* Content read length coded over 1 byte in 2nd byte
1991                * of BER-TLV length field */
1992               LOG(VERBOSE) << StringPrintf(
1993                   "%s - Content read length expected: 0x%02X, returned: 0x%02X",
1994                   __func__, *(p + 2), p_r_apdu->len);
1995               if (*(p + 2) == p_r_apdu->len) {
1996                 if ((p_r_apdu->len > 0) &&
1997                     (p_r_apdu->len <= p_t4t->rw_length)) {
1998                   p_t4t->rw_length -= p_r_apdu->len;
1999                   p_t4t->rw_offset += p_r_apdu->len;
2000                 }
2001               } else {
2002                 LOG(ERROR) << StringPrintf(
2003                     "%s - invalid payload length (%d), rw_length "
2004                     "(%d)",
2005                     __func__, p_r_apdu->len, p_t4t->rw_length);
2006                 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2007                 break;
2008               }
2009             } else {
2010               LOG(ERROR) << StringPrintf(
2011                   "%s - invalid DDO length content length received (1)",
2012                   __func__);
2013               rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2014               break;
2015             }
2016           } else if (*(p + 1) == 0x82) {
2017             /* Content read length coded over 2 bytes in 2nd and 3rd bytes
2018              * of BER-TLV length field*/
2019             r_apdu_len = (uint16_t)(*(p + 2) << 8);
2020             r_apdu_len |= (uint16_t) * (p + 3);
2021             if (r_apdu_len <= (p_t4t->max_read_size - 4)) {
2022               p_r_apdu->len -= 4;
2023               p_r_apdu->offset += 4;
2024               LOG(VERBOSE) << StringPrintf(
2025                   "%s - Content read length expected: 0x%02X%02X, returned: "
2026                   "0x%02X%02X ",
2027                   __func__, *(p + 3), *(p + 2), (uint8_t)(p_r_apdu->len >> 8),
2028                   (uint8_t)p_r_apdu->len);
2029               if (r_apdu_len == p_r_apdu->len) {
2030                 if ((p_r_apdu->len > 0) &&
2031                     (p_r_apdu->len <= p_t4t->rw_length)) {
2032                   p_t4t->rw_length -= p_r_apdu->len;
2033                   p_t4t->rw_offset += p_r_apdu->len;
2034                 }
2035               } else {
2036                 LOG(ERROR) << StringPrintf(
2037                     "%s - invalid payload length (%d), rw_length "
2038                     "(%d)",
2039                     __func__, p_r_apdu->len, p_t4t->rw_length);
2040                 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2041                 break;
2042               }
2043             }
2044           } else {
2045             LOG(ERROR) << StringPrintf(
2046                 "%s - invalid DDO length content length received (2)",
2047                 __func__);
2048             rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2049             break;
2050           }
2051         } else {
2052           LOG(ERROR) << StringPrintf("%s - invalid DDO tag", __func__);
2053           rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2054           break;
2055         }
2056       } else if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length)) {
2057         p_t4t->rw_length -= p_r_apdu->len;
2058         p_t4t->rw_offset += p_r_apdu->len;
2059       } else {
2060         if ((p_r_apdu->len == 0) &&
2061             (p_t4t->cc_file.version == T4T_VERSION_2_0) &&
2062             (p_t4t->intl_flags & RW_T4T_EXT_FIELD_CODING)) {
2063           /* Workaround for tags not fully compliant (declaring MLe or MLc
2064            * higher than respectively 256 and 255 bytes) answering with
2065            * an R-APDU containing no data.
2066            * Assume they do not support Extended Field coding */
2067 
2068           p_t4t->intl_flags &= ~RW_T4T_EXT_FIELD_CODING;
2069 
2070           if (p_t4t->p_retry_cmd) {
2071             GKI_freebuf(p_r_apdu);
2072             p_r_apdu = nullptr;
2073             /* Re-send last command using Short Field coding */
2074             rw_t4t_format_short_field_coding();
2075             return;
2076           }
2077         }
2078         LOG(ERROR) << StringPrintf(
2079             "%s - invalid payload length (%d), rw_length (%d)", __func__,
2080             p_r_apdu->len, p_t4t->rw_length);
2081         rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
2082         break;
2083       }
2084       if (rw_cb.p_cback) {
2085         rw_data.data.status = NFC_STATUS_OK;
2086         rw_data.data.p_data = p_r_apdu;
2087 
2088         /* if need to read more data */
2089         if (p_t4t->rw_length > 0) {
2090           (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_EVT, &rw_data);
2091 
2092           if (!rw_t4t_read_file(p_t4t->rw_offset, p_t4t->rw_length, true)) {
2093             rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2094           }
2095         } else {
2096           p_t4t->state = RW_T4T_STATE_IDLE;
2097 
2098           (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_CPLT_EVT, &rw_data);
2099 
2100           LOG(VERBOSE) << StringPrintf("%s - Sent RW_T4T_NDEF_READ_CPLT_EVT",
2101                                      __func__);
2102         }
2103 
2104         p_r_apdu = nullptr;
2105       } else {
2106         p_t4t->rw_length = 0;
2107         p_t4t->state = RW_T4T_STATE_IDLE;
2108       }
2109       break;
2110 
2111     default:
2112       LOG(ERROR) << StringPrintf("%s - unknown sub_state = %d", __func__,
2113                                  p_t4t->sub_state);
2114       rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2115       break;
2116   }
2117 
2118   if (p_r_apdu) GKI_freebuf(p_r_apdu);
2119 }
2120 
2121 /*******************************************************************************
2122 **
2123 ** Function         rw_t4t_sm_update_ndef
2124 **
2125 ** Description      State machine for NDEF update procedure
2126 **
2127 ** Returns          none
2128 **
2129 *******************************************************************************/
rw_t4t_sm_update_ndef(NFC_HDR * p_r_apdu)2130 static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu) {
2131   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2132   uint8_t* p;
2133   uint16_t status_words;
2134   tRW_DATA rw_data;
2135 
2136   LOG(VERBOSE) << StringPrintf(
2137       "%s - sub_state:%s (%d)", __func__,
2138       rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(), p_t4t->sub_state);
2139 
2140   /* Get status words */
2141   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
2142   p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
2143   BE_STREAM_TO_UINT16(status_words, p);
2144 
2145   if (status_words != T4T_RSP_CMD_CMPLTED) {
2146     rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
2147     return;
2148   }
2149 
2150   switch (p_t4t->sub_state) {
2151     case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
2152 
2153       /* NLEN has been updated */
2154       /* if need to update data */
2155       if (p_t4t->p_update_data) {
2156         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_RESP;
2157 
2158         if (!rw_t4t_update_file()) {
2159           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2160           p_t4t->p_update_data = nullptr;
2161         }
2162       } else {
2163         p_t4t->state = RW_T4T_STATE_IDLE;
2164 
2165         /* just finished last step of updating (updating NLEN) */
2166         if (rw_cb.p_cback) {
2167           rw_data.status = NFC_STATUS_OK;
2168 
2169           (*(rw_cb.p_cback))(RW_T4T_NDEF_UPDATE_CPLT_EVT, &rw_data);
2170           LOG(VERBOSE) << StringPrintf("%s - Sent RW_T4T_NDEF_UPDATE_CPLT_EVT",
2171                                      __func__);
2172         }
2173       }
2174       break;
2175 
2176     case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
2177 
2178       /* if updating is not completed */
2179       if (p_t4t->rw_length > 0) {
2180         if (!rw_t4t_update_file()) {
2181           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2182           p_t4t->p_update_data = nullptr;
2183         }
2184       } else {
2185         p_t4t->p_update_data = nullptr;
2186 
2187         /* update NLEN as last step of updating file */
2188         if (!rw_t4t_update_nlen(p_t4t->ndef_length)) {
2189           rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2190         } else {
2191           p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
2192         }
2193       }
2194       break;
2195 
2196     default:
2197       LOG(ERROR) << StringPrintf("%s - unknown sub_state = %d", __func__,
2198                                  p_t4t->sub_state);
2199       rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2200       break;
2201   }
2202 }
2203 
2204 /*******************************************************************************
2205 **
2206 ** Function         rw_t4t_sm_set_readonly
2207 **
2208 ** Description      State machine for CC update procedure
2209 **
2210 ** Returns          none
2211 **
2212 *******************************************************************************/
rw_t4t_sm_set_readonly(NFC_HDR * p_r_apdu)2213 static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu) {
2214   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2215   uint8_t* p;
2216   uint16_t status_words;
2217   tRW_DATA rw_data;
2218 
2219   LOG(VERBOSE) << StringPrintf(
2220       "%s - sub_state:%s (%d)", __func__,
2221       rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(), p_t4t->sub_state);
2222 
2223   /* Get status words */
2224   p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
2225   p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
2226   BE_STREAM_TO_UINT16(status_words, p);
2227 
2228   if (status_words != T4T_RSP_CMD_CMPLTED) {
2229     rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
2230     return;
2231   }
2232 
2233   switch (p_t4t->sub_state) {
2234     case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
2235 
2236       /* CC file has been selected then update write access to read-only in CC
2237        * file */
2238       if (!rw_t4t_update_cc_to_readonly()) {
2239         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2240       } else {
2241         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_CC;
2242       }
2243       break;
2244 
2245     case RW_T4T_SUBSTATE_WAIT_UPDATE_CC:
2246       /* CC Updated, Select NDEF File to allow NDEF operation */
2247       p_t4t->cc_file.ndef_fc.write_access = T4T_FC_NO_WRITE_ACCESS;
2248       p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
2249 
2250       if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
2251         rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2252       } else {
2253         p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
2254       }
2255       break;
2256 
2257     case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
2258       p_t4t->state = RW_T4T_STATE_IDLE;
2259       /* just finished last step of configuring tag read only (Selecting NDEF
2260        * file CC) */
2261       if (rw_cb.p_cback) {
2262         rw_data.status = NFC_STATUS_OK;
2263 
2264         LOG(VERBOSE) << StringPrintf("%s - Sent RW_T4T_SET_TO_RO_EVT", __func__);
2265         (*(rw_cb.p_cback))(RW_T4T_SET_TO_RO_EVT, &rw_data);
2266       }
2267       break;
2268 
2269     default:
2270       LOG(ERROR) << StringPrintf("%s - unknown sub_state = %d", __func__,
2271                                  p_t4t->sub_state);
2272       rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2273       break;
2274   }
2275 }
2276 
2277 /*******************************************************************************
2278 **
2279 ** Function         rw_t4t_process_timeout
2280 **
2281 ** Description      process timeout event
2282 **
2283 ** Returns          none
2284 **
2285 *******************************************************************************/
rw_t4t_process_timeout(TIMER_LIST_ENT * p_tle)2286 void rw_t4t_process_timeout(TIMER_LIST_ENT* p_tle) {
2287   LOG(VERBOSE) << StringPrintf("event=%d", p_tle->event);
2288 
2289   if (p_tle->event == NFC_TTYPE_RW_T4T_RESPONSE) {
2290     rw_t4t_handle_error(NFC_STATUS_TIMEOUT, 0, 0);
2291   } else {
2292     LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
2293   }
2294 }
2295 
2296 /*******************************************************************************
2297 **
2298 ** Function         rw_t4t_handle_isodep_nak_rsp
2299 **
2300 ** Description      This function handles the response and ntf .
2301 **
2302 ** Returns          none
2303 **
2304 *******************************************************************************/
rw_t4t_handle_isodep_nak_rsp(uint8_t status,bool is_ntf)2305 void rw_t4t_handle_isodep_nak_rsp(uint8_t status, bool is_ntf) {
2306   tRW_DATA rw_data;
2307   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2308   LOG(VERBOSE) << StringPrintf("rw_t4t_handle_isodep_nak_rsp %d", status);
2309   if (is_ntf || (status != NFC_STATUS_OK)) {
2310     rw_data.status = status;
2311     nfc_stop_quick_timer(&p_t4t->timer);
2312     p_t4t->state = RW_T4T_STATE_IDLE;
2313     (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
2314   }
2315 }
2316 
2317 /*******************************************************************************
2318 **
2319 ** Function         rw_t4t_handle_isodep_nak_fallback
2320 **
2321 ** Description      This function resets the state in case of fallback mechanism
2322 **                  encountering a timeout.
2323 **
2324 ** Returns          none
2325 **
2326 *******************************************************************************/
rw_t4t_handle_isodep_nak_fallback()2327 void rw_t4t_handle_isodep_nak_fallback() {
2328   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2329   LOG(VERBOSE) << StringPrintf("rw_t4t_handle_isodep_nak_fallback");
2330   p_t4t->state = RW_T4T_STATE_IDLE;
2331 }
2332 
2333 /*******************************************************************************
2334 **
2335 ** Function         rw_t4t_data_cback
2336 **
2337 ** Description      This callback function receives the data from NFCC.
2338 **
2339 ** Returns          none
2340 **
2341 *******************************************************************************/
rw_t4t_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2342 static void rw_t4t_data_cback(__attribute__((unused)) uint8_t conn_id,
2343                               tNFC_CONN_EVT event, tNFC_CONN* p_data) {
2344   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2345   NFC_HDR* p_r_apdu;
2346   tRW_DATA rw_data;
2347 
2348   uint8_t begin_state = p_t4t->state;
2349 
2350   LOG(VERBOSE) << StringPrintf("%s - event = 0x%X", __func__, event);
2351   nfc_stop_quick_timer(&p_t4t->timer);
2352 
2353   switch (event) {
2354     case NFC_DEACTIVATE_CEVT:
2355       NFC_SetStaticRfCback(nullptr);
2356       p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED;
2357       return;
2358 
2359     case NFC_ERROR_CEVT:
2360       if (p_t4t->state == RW_T4T_STATE_PRESENCE_CHECK) {
2361         p_t4t->state = RW_T4T_STATE_IDLE;
2362         rw_data.status = NFC_STATUS_FAILED;
2363         (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
2364       } else if (p_t4t->state == RW_T4T_STATE_NDEF_FORMAT) {
2365         p_t4t->state = RW_T4T_STATE_IDLE;
2366         rw_data.status = NFC_STATUS_FAILED;
2367         (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
2368       } else if (p_t4t->state != RW_T4T_STATE_IDLE) {
2369         rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
2370         rw_t4t_handle_error(rw_data.status, 0, 0);
2371       } else {
2372         p_t4t->state = RW_T4T_STATE_IDLE;
2373         rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
2374         (*(rw_cb.p_cback))(RW_T4T_INTF_ERROR_EVT, &rw_data);
2375       }
2376       return;
2377 
2378     case NFC_DATA_CEVT:
2379       p_r_apdu = (NFC_HDR*)p_data->data.p_data;
2380       break;
2381 
2382     default:
2383       return;
2384   }
2385 
2386   LOG(VERBOSE) << StringPrintf("%s - RW T4T state: <%s (%d)>", __func__,
2387                              rw_t4t_get_state_name(p_t4t->state).c_str(),
2388                              p_t4t->state);
2389 
2390   if (p_t4t->state != RW_T4T_STATE_IDLE &&
2391       p_t4t->state != RW_T4T_STATE_PRESENCE_CHECK &&
2392       p_r_apdu->len < T4T_RSP_STATUS_WORDS_SIZE) {
2393     LOG(ERROR) << StringPrintf("%s incorrect p_r_apdu length", __func__);
2394     android_errorWriteLog(0x534e4554, "120865977");
2395     rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2396     GKI_freebuf(p_r_apdu);
2397     return;
2398   }
2399 
2400   switch (p_t4t->state) {
2401     case RW_T4T_STATE_IDLE:
2402       /* Unexpected R-APDU, it should be raw frame response */
2403       /* forward to upper layer without parsing */
2404       LOG(VERBOSE) << StringPrintf(
2405           "%s - RW T4T Raw Frame: Len [0x%X] Status [%s]", __func__,
2406           p_r_apdu->len, NFC_GetStatusName(p_data->data.status).c_str());
2407       if (rw_cb.p_cback) {
2408         rw_data.raw_frame.status = p_data->data.status;
2409         rw_data.raw_frame.p_data = p_r_apdu;
2410         (*(rw_cb.p_cback))(RW_T4T_RAW_FRAME_EVT, &rw_data);
2411         p_r_apdu = nullptr;
2412       } else {
2413         GKI_freebuf(p_r_apdu);
2414       }
2415       break;
2416     case RW_T4T_STATE_DETECT_NDEF:
2417       rw_t4t_sm_detect_ndef(p_r_apdu);
2418       GKI_freebuf(p_r_apdu);
2419       break;
2420     case RW_T4T_STATE_READ_NDEF:
2421       rw_t4t_sm_read_ndef(p_r_apdu);
2422       /* p_r_apdu may send upper lyaer */
2423       break;
2424     case RW_T4T_STATE_UPDATE_NDEF:
2425       rw_t4t_sm_update_ndef(p_r_apdu);
2426       GKI_freebuf(p_r_apdu);
2427       break;
2428     case RW_T4T_STATE_PRESENCE_CHECK:
2429       /* if any response, send presence check with ok */
2430       rw_data.status = NFC_STATUS_OK;
2431       p_t4t->state = RW_T4T_STATE_IDLE;
2432       (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
2433       GKI_freebuf(p_r_apdu);
2434       break;
2435     case RW_T4T_STATE_SET_READ_ONLY:
2436       rw_t4t_sm_set_readonly(p_r_apdu);
2437       GKI_freebuf(p_r_apdu);
2438       break;
2439     case RW_T4T_STATE_NDEF_FORMAT:
2440       rw_t4t_sm_ndef_format(p_r_apdu);
2441       GKI_freebuf(p_r_apdu);
2442       break;
2443     default:
2444       LOG(ERROR) << StringPrintf("%s - invalid state=%d", __func__,
2445                                  p_t4t->state);
2446       GKI_freebuf(p_r_apdu);
2447       break;
2448   }
2449 
2450   if (begin_state != p_t4t->state) {
2451     LOG(VERBOSE) << StringPrintf("%s - RW T4T state changed:<%s> -> <%s>",
2452                                __func__,
2453                                rw_t4t_get_state_name(begin_state).c_str(),
2454                                rw_t4t_get_state_name(p_t4t->state).c_str());
2455   }
2456 }
2457 
2458 /*******************************************************************************
2459 **
2460 ** Function         rw_t4t_ndefee_init_cb
2461 **
2462 ** Description      Initialize T4T
2463 **
2464 ** Returns          NFC_STATUS_OK if success
2465 **
2466 *******************************************************************************/
RW_T4tNfceeInitCb(void)2467 tNFC_STATUS RW_T4tNfceeInitCb(void) {
2468   LOG(DEBUG) << StringPrintf("%s Enter ", __func__);
2469   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2470 
2471   LOG(DEBUG) << StringPrintf("rw_t4t_ndefee_select ()");
2472 
2473   NFC_SetStaticT4tNfceeCback(rw_t4t_data_cback, nfa_t4tnfcee_cb.connId);
2474 
2475   p_t4t->state = RW_T4T_STATE_IDLE;
2476   p_t4t->version = T4T_MY_VERSION;
2477   /* set it min of max R-APDU data size before reading CC file */
2478   p_t4t->cc_file.max_le = T4T_MIN_MLE;
2479 
2480   /* These will be udated during NDEF detection */
2481   p_t4t->max_read_size = T4T_MAX_LENGTH_LE - T4T_FILE_LENGTH_SIZE;
2482   p_t4t->max_update_size = RW_T4TNFCEE_DATA_PER_WRITE;
2483 
2484   return NFC_STATUS_OK;
2485 }
2486 
2487 /*******************************************************************************
2488 **
2489 ** Function         RW_T4tNfceeUpdateCC
2490 **
2491 ** Description      Updates the T4T data structures with CC info
2492 **
2493 ** Returns          None
2494 **
2495 *******************************************************************************/
RW_T4tNfceeUpdateCC(uint8_t * ccInfo)2496 void RW_T4tNfceeUpdateCC(uint8_t* ccInfo) {
2497   LOG(DEBUG) << StringPrintf("%s Enter", __func__);
2498   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2499   BE_STREAM_TO_UINT16(p_t4t->cc_file.max_le, ccInfo);
2500   BE_STREAM_TO_UINT16(p_t4t->cc_file.max_lc, ccInfo);
2501 
2502   /* Get max bytes to read per command */
2503   if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ) {
2504     p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
2505   } else {
2506     p_t4t->max_read_size = p_t4t->cc_file.max_le;
2507   }
2508 
2509   /* Le: valid range is 0x01 to 0xFF */
2510   if (p_t4t->max_read_size >= T4T_MAX_LENGTH_LE) {
2511     p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
2512   }
2513 
2514   /* Get max bytes to update per command */
2515   if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE) {
2516     p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
2517   } else {
2518     p_t4t->max_update_size = p_t4t->cc_file.max_lc;
2519   }
2520   /* Lc: valid range is 0x01 to 0xFF */
2521   if (p_t4t->max_update_size >= T4T_MAX_LENGTH_LC) {
2522     p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
2523   }
2524 
2525   LOG(DEBUG) << StringPrintf(
2526       "%s le %d  lc: %d  max_read_size: %d max_update_size: %d", __func__,
2527       p_t4t->cc_file.max_le, p_t4t->cc_file.max_lc, p_t4t->max_read_size,
2528       p_t4t->max_update_size);
2529 }
2530 
2531 /*******************************************************************************
2532 **
2533 ** Function         RW_T4tNfceeSelectApplication
2534 **
2535 ** Description      Selects T4T application using T4T AID
2536 **
2537 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2538 **
2539 *******************************************************************************/
RW_T4tNfceeSelectApplication(void)2540 tNFC_STATUS RW_T4tNfceeSelectApplication(void) {
2541   LOG(DEBUG) << StringPrintf("%s Enter", __func__);
2542   if (!rw_t4t_select_application(T4T_VERSION_2_0)) {
2543     return NFC_STATUS_FAILED;
2544   } else
2545     return NFC_STATUS_OK;
2546 }
2547 /*******************************************************************************
2548 **
2549 ** Function         RW_T4tNfceeSelectFile
2550 **
2551 ** Description      Selects T4T Nfcee File
2552 **
2553 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2554 **
2555 *******************************************************************************/
RW_T4tNfceeSelectFile(uint16_t fileId)2556 tNFC_STATUS RW_T4tNfceeSelectFile(uint16_t fileId) {
2557   LOG(DEBUG) << StringPrintf("%s Enter", __func__);
2558   if (!rw_t4t_select_file(fileId)) {
2559     return NFC_STATUS_FAILED;
2560   } else
2561     return NFC_STATUS_OK;
2562 }
2563 
2564 /*******************************************************************************
2565 **
2566 ** Function         RW_T4tNfceeReadDataLen
2567 **
2568 ** Description      Reads proprietary data Len
2569 **
2570 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2571 **
2572 *******************************************************************************/
RW_T4tNfceeReadDataLen()2573 tNFC_STATUS RW_T4tNfceeReadDataLen() {
2574   LOG(DEBUG) << StringPrintf("%s Enter ", __func__);
2575   if (!rw_t4t_read_file(0x00, T4T_FILE_LENGTH_SIZE, false)) {
2576     rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2577     return NFC_STATUS_FAILED;
2578   }
2579   return NFC_STATUS_OK;
2580 }
2581 
2582 /*******************************************************************************
2583 **
2584 ** Function         RW_T4tNfceeReadFile
2585 **
2586 ** Description      Reads T4T Nfcee File
2587 **
2588 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2589 **
2590 *******************************************************************************/
RW_T4tNfceeReadFile(uint16_t offset,uint16_t Readlen)2591 tNFC_STATUS RW_T4tNfceeReadFile(uint16_t offset, uint16_t Readlen) {
2592   // tNFC_STATUS status = NFC_STATUS_FAILED;
2593   LOG(DEBUG) << StringPrintf("%s Enter : Readlen : 0x%x", __func__, Readlen);
2594   if (!rw_t4t_read_file(offset, Readlen, false)) {
2595     rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2596     return NFC_STATUS_FAILED;
2597   }
2598   return NFC_STATUS_OK;
2599 }
2600 
2601 /*******************************************************************************
2602 **
2603 ** Function         RW_T4tNfceeReadPendingData
2604 **
2605 ** Description      Reads pending data from T4T Nfcee File
2606 **
2607 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2608 **
2609 *******************************************************************************/
RW_T4tNfceeReadPendingData()2610 tNFC_STATUS RW_T4tNfceeReadPendingData() {
2611   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2612   p_t4t->rw_length -= p_t4t->max_read_size;
2613   p_t4t->rw_offset += p_t4t->max_read_size;
2614   if (!rw_t4t_read_file(p_t4t->rw_offset, p_t4t->rw_length, true)) {
2615     rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2616     return NFC_STATUS_FAILED;
2617   }
2618   return NFC_STATUS_OK;
2619 }
2620 
2621 /*******************************************************************************
2622 **
2623 ** Function         RW_T4tNfceeUpdateNlen
2624 **
2625 ** Description      writes requested length to the file
2626 **
2627 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2628 **
2629 *******************************************************************************/
RW_T4tNfceeUpdateNlen(uint16_t len)2630 tNFC_STATUS RW_T4tNfceeUpdateNlen(uint16_t len) {
2631   LOG(DEBUG) << StringPrintf("%s Enter ", __func__);
2632   /* update nlen_size with T4T_FILE_LENGTH_SIZE to avoid mismatch in
2633    * reading/writing length of data*/
2634   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2635   p_t4t->cc_file.ndef_fc.nlen_size = T4T_FILE_LENGTH_SIZE;
2636   if (!rw_t4t_update_nlen(len)) {
2637     return NFC_STATUS_FAILED;
2638   }
2639   return NFC_STATUS_OK;
2640 }
2641 
2642 /*******************************************************************************
2643 **
2644 ** Function         RW_T4tNfceeStartUpdateFile
2645 **
2646 ** Description      starts writing data to the currently selected file
2647 **
2648 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2649 **
2650 *******************************************************************************/
RW_T4tNfceeStartUpdateFile(uint16_t length,uint8_t * p_data)2651 tNFC_STATUS RW_T4tNfceeStartUpdateFile(uint16_t length, uint8_t* p_data) {
2652   LOG(DEBUG) << StringPrintf("%s Enter ", __func__);
2653   rw_cb.tcb.t4t.p_update_data = p_data;
2654   rw_cb.tcb.t4t.rw_offset = T4T_FILE_LENGTH_SIZE;
2655   rw_cb.tcb.t4t.rw_length = length;
2656   return RW_T4tNfceeUpdateFile();
2657 }
2658 
2659 /*******************************************************************************
2660 **
2661 ** Function         RW_T4tNfceeUpdateFile
2662 **
2663 ** Description      writes requested data to the currently selected file
2664 **
2665 ** Returns          NFC_STATUS_OK if success else NFC_STATUS_FAILED
2666 **
2667 *******************************************************************************/
RW_T4tNfceeUpdateFile()2668 tNFC_STATUS RW_T4tNfceeUpdateFile() {
2669   LOG(DEBUG) << StringPrintf("%s Enter ", __func__);
2670   if (!rw_t4t_update_file()) {
2671     rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
2672     rw_cb.tcb.t4t.p_update_data = nullptr;
2673     return NFC_STATUS_FAILED;
2674   }
2675   return NFC_STATUS_OK;
2676 }
2677 
2678 /*******************************************************************************
2679 **
2680 ** Function         RW_T4tIsUpdateComplete
2681 **
2682 ** Description      Return true if no more data to write
2683 **
2684 ** Returns          true/false
2685 **
2686 *******************************************************************************/
RW_T4tIsUpdateComplete(void)2687 bool RW_T4tIsUpdateComplete(void) { return (rw_cb.tcb.t4t.rw_length == 0); }
2688 
2689 /*******************************************************************************
2690 **
2691 ** Function         RW_T4tIsReadComplete
2692 **
2693 ** Description      Return true if no more data to be read
2694 **
2695 ** Returns          true/false
2696 **
2697 *******************************************************************************/
RW_T4tIsReadComplete(void)2698 bool RW_T4tIsReadComplete(void) {
2699   return (rw_cb.tcb.t4t.rw_length <= rw_cb.tcb.t4t.max_read_size);
2700 }
2701 
2702 /*******************************************************************************
2703 **
2704 ** Function         RW_T4tFormatNDef
2705 **
2706 ** Description      format T4T tag
2707 **
2708 ** Returns          NFC_STATUS_OK if success
2709 **
2710 *******************************************************************************/
RW_T4tFormatNDef(void)2711 tNFC_STATUS RW_T4tFormatNDef(void) {
2712   LOG(VERBOSE) << __func__;
2713 
2714   if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2715     LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
2716                                rw_cb.tcb.t4t.state);
2717     return NFC_STATUS_FAILED;
2718   }
2719 
2720   rw_cb.tcb.t4t.card_type = 0x00;
2721 
2722   if (!rw_t4t_get_hw_version()) {
2723     return NFC_STATUS_FAILED;
2724   }
2725 
2726   rw_cb.tcb.t4t.state = RW_T4T_STATE_NDEF_FORMAT;
2727   rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION;
2728 
2729   return NFC_STATUS_OK;
2730 }
2731 
2732 /*******************************************************************************
2733 **
2734 ** Function         rw_t4t_select
2735 **
2736 ** Description      Initialise T4T
2737 **
2738 ** Returns          NFC_STATUS_OK if success
2739 **
2740 *******************************************************************************/
rw_t4t_select(void)2741 tNFC_STATUS rw_t4t_select(void) {
2742   tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
2743 
2744   LOG(VERBOSE) << __func__;
2745 
2746   NFC_SetStaticRfCback(rw_t4t_data_cback);
2747 
2748   p_t4t->state = RW_T4T_STATE_IDLE;
2749   p_t4t->version = T4T_MY_VERSION;
2750 
2751   /* set it min of max R-APDU data size before reading CC file */
2752   p_t4t->cc_file.max_le = T4T_MIN_MLE;
2753 
2754   /* These will be udated during NDEF detection */
2755   p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
2756   p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
2757 
2758   return NFC_STATUS_OK;
2759 }
2760 
2761 /*******************************************************************************
2762 **
2763 ** Function         RW_T4tDetectNDef
2764 **
2765 ** Description      This function performs NDEF detection procedure
2766 **
2767 **                  RW_T4T_NDEF_DETECT_EVT will be returned
2768 **
2769 ** Returns          NFC_STATUS_OK if success
2770 **                  NFC_STATUS_FAILED if T4T is busy or other error
2771 **
2772 *******************************************************************************/
RW_T4tDetectNDef(void)2773 tNFC_STATUS RW_T4tDetectNDef(void) {
2774   LOG(VERBOSE) << __func__;
2775 
2776   if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2777     LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
2778                                __func__, rw_cb.tcb.t4t.state);
2779     return NFC_STATUS_FAILED;
2780   }
2781 
2782   if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
2783     /* NDEF Tag application has been selected then select CC file */
2784     if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
2785       return NFC_STATUS_FAILED;
2786     }
2787     rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
2788   } else {
2789     /* Select NDEF Tag Application */
2790     if (!rw_t4t_select_application(rw_cb.tcb.t4t.version)) {
2791       return NFC_STATUS_FAILED;
2792     }
2793     rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
2794   }
2795 
2796   rw_cb.tcb.t4t.state = RW_T4T_STATE_DETECT_NDEF;
2797 
2798   return NFC_STATUS_OK;
2799 }
2800 
2801 /*******************************************************************************
2802 **
2803 ** Function         RW_T4tReadNDef
2804 **
2805 ** Description      This function performs NDEF read procedure
2806 **                  Note: RW_T4tDetectNDef () must be called before using this
2807 **
2808 **                  The following event will be returned
2809 **                      RW_T4T_NDEF_READ_EVT for each segmented NDEF message
2810 **                      RW_T4T_NDEF_READ_CPLT_EVT for the last segment or
2811 **                      complete NDEF
2812 **                      RW_T4T_NDEF_READ_FAIL_EVT for failure
2813 **
2814 ** Returns          NFC_STATUS_OK if success
2815 **                  NFC_STATUS_FAILED if T4T is busy or other error
2816 **
2817 *******************************************************************************/
RW_T4tReadNDef(void)2818 tNFC_STATUS RW_T4tReadNDef(void) {
2819   LOG(VERBOSE) << __func__;
2820 
2821   if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2822     LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
2823                                __func__, rw_cb.tcb.t4t.state);
2824     return NFC_STATUS_FAILED;
2825   }
2826 
2827   /* if NDEF has been detected */
2828   if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
2829     /* start reading NDEF */
2830     if (!rw_t4t_read_file(rw_cb.tcb.t4t.cc_file.ndef_fc.nlen_size,
2831                           rw_cb.tcb.t4t.ndef_length, false)) {
2832       return NFC_STATUS_FAILED;
2833     }
2834 
2835     rw_cb.tcb.t4t.state = RW_T4T_STATE_READ_NDEF;
2836     rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
2837 
2838     return NFC_STATUS_OK;
2839   } else {
2840     LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
2841     return NFC_STATUS_FAILED;
2842   }
2843 }
2844 
2845 /*******************************************************************************
2846 **
2847 ** Function         RW_T4tUpdateNDef
2848 **
2849 ** Description      This function performs NDEF update procedure
2850 **                  Note: RW_T4tDetectNDef () must be called before using this
2851 **                        Updating data must not be removed until returning
2852 **                        event
2853 **
2854 **                  The following event will be returned
2855 **                      RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
2856 **                      RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
2857 **
2858 ** Returns          NFC_STATUS_OK if success
2859 **                  NFC_STATUS_FAILED if T4T is busy or other error
2860 **
2861 *******************************************************************************/
RW_T4tUpdateNDef(uint32_t length,uint8_t * p_data)2862 tNFC_STATUS RW_T4tUpdateNDef(uint32_t length, uint8_t* p_data) {
2863   LOG(VERBOSE) << StringPrintf("%s - length:%d", __func__, length);
2864 
2865   if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2866     LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
2867                                __func__, rw_cb.tcb.t4t.state);
2868     return NFC_STATUS_FAILED;
2869   }
2870 
2871   /* if NDEF has been detected */
2872   if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
2873     /* if read-only */
2874     if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
2875       LOG(ERROR) << StringPrintf("%s - NDEF is read-only", __func__);
2876       return NFC_STATUS_FAILED;
2877     }
2878 
2879     if (rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size <
2880         length + rw_cb.tcb.t4t.cc_file.ndef_fc.nlen_size) {
2881       LOG(ERROR) << StringPrintf(
2882           "%s - data (%d bytes) plus NLEN is more than max file "
2883           "size (%d)",
2884           __func__, length, rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size);
2885       return NFC_STATUS_FAILED;
2886     }
2887 
2888     /* store NDEF length and data */
2889     rw_cb.tcb.t4t.ndef_length = length;
2890     rw_cb.tcb.t4t.p_update_data = p_data;
2891 
2892     rw_cb.tcb.t4t.rw_offset = rw_cb.tcb.t4t.cc_file.ndef_fc.nlen_size;
2893     rw_cb.tcb.t4t.rw_length = length;
2894 
2895     /* set NLEN to 0x0000 for the first step */
2896     if (!rw_t4t_update_nlen(0x0000)) {
2897       return NFC_STATUS_FAILED;
2898     }
2899 
2900     rw_cb.tcb.t4t.state = RW_T4T_STATE_UPDATE_NDEF;
2901     rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
2902 
2903     return NFC_STATUS_OK;
2904   } else {
2905     LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
2906     return NFC_STATUS_FAILED;
2907   }
2908 }
2909 
2910 /*****************************************************************************
2911 **
2912 ** Function         RW_T4tPresenceCheck
2913 **
2914 ** Description
2915 **      Check if the tag is still in the field.
2916 **
2917 **      The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2918 **      or non-presence.
2919 **
2920 **      option is RW_T4T_CHK_EMPTY_I_BLOCK, use empty I block for presence check
2921 **
2922 ** Returns
2923 **      NFC_STATUS_OK, if raw data frame sent
2924 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2925 **      NFC_STATUS_FAILED: other error
2926 **
2927 *****************************************************************************/
RW_T4tPresenceCheck(uint8_t option)2928 tNFC_STATUS RW_T4tPresenceCheck(uint8_t option) {
2929   tNFC_STATUS retval = NFC_STATUS_OK;
2930   tRW_DATA evt_data;
2931   bool status;
2932   NFC_HDR* p_data;
2933 
2934   LOG(VERBOSE) << StringPrintf("%s - %d", __func__, option);
2935 
2936   /* If RW_SelectTagType was not called (no conn_callback) return failure */
2937   if (!rw_cb.p_cback) {
2938     retval = NFC_STATUS_FAILED;
2939   }
2940   /* If we are not activated, then RW_T4T_PRESENCE_CHECK_EVT with
2941      NFC_STATUS_FAILED */
2942   else if (rw_cb.tcb.t4t.state == RW_T4T_STATE_NOT_ACTIVATED) {
2943     evt_data.status = NFC_STATUS_FAILED;
2944     (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
2945   }
2946   /* If command is pending, assume tag is still present */
2947   else if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2948     evt_data.status = NFC_STATUS_OK;
2949     (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
2950   } else {
2951     status = false;
2952     if (option == RW_T4T_CHK_EMPTY_I_BLOCK) {
2953       /* use empty I block for presence check */
2954       p_data = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + NCI_MSG_OFFSET_SIZE +
2955                                     NCI_DATA_HDR_SIZE);
2956       if (p_data != nullptr) {
2957         p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
2958         p_data->len = 0;
2959         if (NFC_SendData(NFC_RF_CONN_ID, (NFC_HDR*)p_data) == NFC_STATUS_OK)
2960           status = true;
2961       }
2962     } else if (option == RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK) {
2963       if (NFC_ISODEPNakPresCheck() == NFC_STATUS_OK) status = true;
2964     }
2965 
2966     if (status == true) {
2967       rw_cb.tcb.t4t.state = RW_T4T_STATE_PRESENCE_CHECK;
2968     } else {
2969       retval = NFC_STATUS_NO_BUFFERS;
2970     }
2971   }
2972 
2973   return (retval);
2974 }
2975 
2976 /*****************************************************************************
2977 **
2978 ** Function         RW_T4tSetNDefReadOnly
2979 **
2980 ** Description      This function performs NDEF read-only procedure
2981 **                  Note: RW_T4tDetectNDef() must be called before using this
2982 **
2983 **                  The RW_T4T_SET_TO_RO_EVT event will be returned.
2984 **
2985 ** Returns          NFC_STATUS_OK if success
2986 **                  NFC_STATUS_FAILED if T4T is busy or other error
2987 **
2988 *****************************************************************************/
RW_T4tSetNDefReadOnly(void)2989 tNFC_STATUS RW_T4tSetNDefReadOnly(void) {
2990   tNFC_STATUS retval = NFC_STATUS_OK;
2991   tRW_DATA evt_data;
2992 
2993   LOG(VERBOSE) << __func__;
2994 
2995   if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2996     LOG(ERROR) << StringPrintf("%s - Unable to start command at state (0x%X)",
2997                                __func__, rw_cb.tcb.t4t.state);
2998     return NFC_STATUS_FAILED;
2999   }
3000 
3001   /* if NDEF has been detected */
3002   if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
3003     /* if read-only */
3004     if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
3005       LOG(VERBOSE) << StringPrintf("%s - NDEF is already read-only", __func__);
3006 
3007       evt_data.status = NFC_STATUS_OK;
3008       (*rw_cb.p_cback)(RW_T4T_SET_TO_RO_EVT, &evt_data);
3009       return (retval);
3010     }
3011 
3012     /* NDEF Tag application has been selected then select CC file */
3013     if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
3014       return NFC_STATUS_FAILED;
3015     }
3016 
3017     rw_cb.tcb.t4t.state = RW_T4T_STATE_SET_READ_ONLY;
3018     rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
3019 
3020     return NFC_STATUS_OK;
3021   } else {
3022     LOG(ERROR) << StringPrintf("%s - No NDEF detected", __func__);
3023     return NFC_STATUS_FAILED;
3024   }
3025   return (retval);
3026 }
3027 
3028 /*******************************************************************************
3029 **
3030 ** Function         rw_t4t_get_state_name
3031 **
3032 ** Description      This function returns the state name.
3033 **
3034 ** NOTE             conditionally compiled to save memory.
3035 **
3036 ** Returns          pointer to the name
3037 **
3038 *******************************************************************************/
rw_t4t_get_state_name(uint8_t state)3039 static std::string rw_t4t_get_state_name(uint8_t state) {
3040   switch (state) {
3041     case RW_T4T_STATE_NOT_ACTIVATED:
3042       return "NOT_ACTIVATED";
3043     case RW_T4T_STATE_IDLE:
3044       return "IDLE";
3045     case RW_T4T_STATE_DETECT_NDEF:
3046       return "NDEF_DETECTION";
3047     case RW_T4T_STATE_READ_NDEF:
3048       return "READ_NDEF";
3049     case RW_T4T_STATE_UPDATE_NDEF:
3050       return "UPDATE_NDEF";
3051     case RW_T4T_STATE_PRESENCE_CHECK:
3052       return "PRESENCE_CHECK";
3053     case RW_T4T_STATE_SET_READ_ONLY:
3054       return "SET_READ_ONLY";
3055     default:
3056       return "???? UNKNOWN STATE";
3057   }
3058 }
3059 
3060 /*******************************************************************************
3061 **
3062 ** Function         rw_t4t_get_sub_state_name
3063 **
3064 ** Description      This function returns the sub_state name.
3065 **
3066 ** NOTE             conditionally compiled to save memory.
3067 **
3068 ** Returns          pointer to the name
3069 **
3070 *******************************************************************************/
rw_t4t_get_sub_state_name(uint8_t sub_state)3071 static std::string rw_t4t_get_sub_state_name(uint8_t sub_state) {
3072   switch (sub_state) {
3073     case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
3074       return "WAIT_SELECT_APP";
3075     case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
3076       return "WAIT_SELECT_CC";
3077     case RW_T4T_SUBSTATE_WAIT_CC_FILE:
3078       return "WAIT_CC_FILE";
3079     case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
3080       return "WAIT_SELECT_NDEF_FILE";
3081     case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
3082       return "WAIT_READ_NLEN";
3083     case RW_T4T_SUBSTATE_WAIT_READ_RESP:
3084       return "WAIT_READ_RESP";
3085     case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
3086       return "WAIT_UPDATE_RESP";
3087     case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
3088       return "WAIT_UPDATE_NLEN";
3089     case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
3090       return "WAIT_GET_HW_VERSION";
3091     case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
3092       return "WAIT_GET_SW_VERSION";
3093     case RW_T4T_SUBSTATE_WAIT_GET_UID:
3094       return "WAIT_GET_UID";
3095     case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
3096       return "WAIT_CREATE_APP";
3097     case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
3098       return "WAIT_CREATE_CC";
3099     case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
3100       return "WAIT_CREATE_NDEF";
3101     case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
3102       return "WAIT_WRITE_CC";
3103     case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
3104       return "WAIT_WRITE_NDEF";
3105     case RW_T4T_SUBSTATE_WAIT_ENDEF_FILE_CTRL_TLV:
3106       return "WAIT_ENDEF_FILE_CTRL_TLV";
3107     default:
3108       return "???? UNKNOWN SUBSTATE";
3109   }
3110 }
3111