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