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