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