blob: fd0bbdff993f6633ff8360ea82908b3c8e1020e6 [file] [log] [blame]
nxpandroidc7611652015-09-23 16:42:05 +05301/******************************************************************************
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 *
nxpandroidc7611652015-09-23 16:42:05 +053021 * This file contains the implementation for Type 4 tag in Reader/Writer
22 * mode.
23 *
24 ******************************************************************************/
25#include <string.h>
nxpandroidc7611652015-09-23 16:42:05 +053026
nxf24591c1cbeab2018-02-21 17:32:26 +053027#include <android-base/stringprintf.h>
28#include <base/logging.h>
29
30#include "nfc_target.h"
31
32#include "bt_types.h"
nxpandroidc7611652015-09-23 16:42:05 +053033#include "nfc_api.h"
34#include "nfc_int.h"
35#include "rw_api.h"
36#include "rw_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053037#include "trace_api.h"
38
39using android::base::StringPrintf;
40
41extern bool nfc_debug_enabled;
nxpandroidc7611652015-09-23 16:42:05 +053042
43/* main state */
nxpandroid8f6d0532017-07-12 18:25:30 +053044/* 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
nxpandroidc7611652015-09-23 16:42:05 +053058
nxpandroid8f6d0532017-07-12 18:25:30 +053059/* performing NDEF format */
60#define RW_T4T_STATE_NDEF_FORMAT 0x07
nxf24591c1cbeab2018-02-21 17:32:26 +053061
nxpandroidc7611652015-09-23 16:42:05 +053062/* sub state */
nxpandroid8f6d0532017-07-12 18:25:30 +053063/* 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
nxpandroidc7611652015-09-23 16:42:05 +053081
nxpandroid8f6d0532017-07-12 18:25:30 +053082#define RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION 0x09
83#define RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION 0x0A
84#define RW_T4T_SUBSTATE_WAIT_GET_UID 0x0B
85#define RW_T4T_SUBSTATE_WAIT_CREATE_APP 0x0C
86#define RW_T4T_SUBSTATE_WAIT_CREATE_CC 0x0D
87#define RW_T4T_SUBSTATE_WAIT_CREATE_NDEF 0x0E
88#define RW_T4T_SUBSTATE_WAIT_WRITE_CC 0x0F
89#define RW_T4T_SUBSTATE_WAIT_WRITE_NDEF 0x10
nxpandroidc7611652015-09-23 16:42:05 +053090
nxf24591c1cbeab2018-02-21 17:32:26 +053091static std::string rw_t4t_get_state_name(uint8_t state);
92static std::string rw_t4t_get_sub_state_name(uint8_t sub_state);
nxpandroidc7611652015-09-23 16:42:05 +053093
nxpandroid8f6d0532017-07-12 18:25:30 +053094static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu);
95static bool rw_t4t_select_file(uint16_t file_id);
96static bool rw_t4t_read_file(uint16_t offset, uint16_t length,
97 bool is_continue);
98static bool rw_t4t_update_nlen(uint16_t ndef_len);
99static bool rw_t4t_update_file(void);
100static bool rw_t4t_update_cc_to_readonly(void);
101static bool rw_t4t_select_application(uint8_t version);
102static bool rw_t4t_validate_cc_file(void);
nxpandroidc7611652015-09-23 16:42:05 +0530103
nxpandroid8f6d0532017-07-12 18:25:30 +0530104static bool rw_t4t_get_hw_version(void);
105static bool rw_t4t_get_sw_version(void);
106static bool rw_t4t_create_app(void);
107static bool rw_t4t_select_app(void);
108static bool rw_t4t_create_ccfile(void);
109static bool rw_t4t_create_ndef(void);
110static bool rw_t4t_write_cc(void);
111static bool rw_t4t_write_ndef(void);
nxpandroid8f6d0532017-07-12 18:25:30 +0530112static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2);
113static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu);
114static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu);
115static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu);
116static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu);
117static void rw_t4t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
118 tNFC_CONN* p_data);
nxf24591c1cbeab2018-02-21 17:32:26 +0530119static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu);
nxpandroidc7611652015-09-23 16:42:05 +0530120
nxpandroidc7611652015-09-23 16:42:05 +0530121/*******************************************************************************
122**
123** Function rw_t4t_send_to_lower
124**
125** Description Send C-APDU to lower layer
126**
nxf24591c1cbeab2018-02-21 17:32:26 +0530127** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530128**
129*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530130static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530131 if (NFC_SendData(NFC_RF_CONN_ID, p_c_apdu) != NFC_STATUS_OK) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530132 LOG(ERROR) << StringPrintf("failed");
nxpandroid8f6d0532017-07-12 18:25:30 +0530133 return false;
134 }
nxpandroidc7611652015-09-23 16:42:05 +0530135
nxpandroid8f6d0532017-07-12 18:25:30 +0530136 nfc_start_quick_timer(&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
137 (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530138
nxpandroid8f6d0532017-07-12 18:25:30 +0530139 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530140}
141
nxpandroidc7611652015-09-23 16:42:05 +0530142/*******************************************************************************
143**
144** Function rw_t4t_get_hw_version
145**
146** Description Send get hw version cmd to peer
147**
nxf24591c1cbeab2018-02-21 17:32:26 +0530148** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530149**
150*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530151static bool rw_t4t_get_hw_version(void) {
152 NFC_HDR* p_c_apdu;
153 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530154
nxpandroid8f6d0532017-07-12 18:25:30 +0530155 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530156
nxpandroid8f6d0532017-07-12 18:25:30 +0530157 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530158 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530159 return false;
160 }
nxpandroidc7611652015-09-23 16:42:05 +0530161
nxpandroid8f6d0532017-07-12 18:25:30 +0530162 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
163 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530164
nxpandroid8f6d0532017-07-12 18:25:30 +0530165 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
166 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_GET_HW_VERSION);
167 UINT16_TO_BE_STREAM(p, 0x0000);
168 UINT8_TO_BE_FIELD(p, 0x00);
nxpandroidc7611652015-09-23 16:42:05 +0530169
nxpandroid8f6d0532017-07-12 18:25:30 +0530170 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530171
nxpandroid8f6d0532017-07-12 18:25:30 +0530172 if (!rw_t4t_send_to_lower(p_c_apdu)) {
173 return false;
174 }
nxpandroidc7611652015-09-23 16:42:05 +0530175
nxpandroid8f6d0532017-07-12 18:25:30 +0530176 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530177}
178
179/*******************************************************************************
180**
181** Function rw_t4t_get_sw_version
182**
183** Description Send get sw version cmd to peer
184**
nxf24591c1cbeab2018-02-21 17:32:26 +0530185** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530186**
187*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530188static bool rw_t4t_get_sw_version(void) {
189 NFC_HDR* p_c_apdu;
190 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530191
nxpandroid8f6d0532017-07-12 18:25:30 +0530192 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530193
nxpandroid8f6d0532017-07-12 18:25:30 +0530194 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530195 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530196 return false;
197 }
nxpandroidc7611652015-09-23 16:42:05 +0530198
nxpandroid8f6d0532017-07-12 18:25:30 +0530199 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
200 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530201
nxpandroid8f6d0532017-07-12 18:25:30 +0530202 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
203 UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
204 UINT16_TO_BE_STREAM(p, 0x0000);
205 UINT8_TO_BE_FIELD(p, 0x00);
nxpandroidc7611652015-09-23 16:42:05 +0530206
nxpandroid8f6d0532017-07-12 18:25:30 +0530207 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530208
nxpandroid8f6d0532017-07-12 18:25:30 +0530209 if (!rw_t4t_send_to_lower(p_c_apdu)) {
210 return false;
211 }
nxpandroidc7611652015-09-23 16:42:05 +0530212
nxpandroid8f6d0532017-07-12 18:25:30 +0530213 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530214}
215
216/*******************************************************************************
217**
218** Function rw_t4t_update_version_details
219**
220** Description Updates the size of the card
221**
nxf24591c1cbeab2018-02-21 17:32:26 +0530222** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530223**
224*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530225static bool rw_t4t_update_version_details(NFC_HDR* p_r_apdu) {
226 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
227 uint8_t* p;
228 uint16_t major_version, minor_version;
nxpandroidc7611652015-09-23 16:42:05 +0530229
nxpandroid8f6d0532017-07-12 18:25:30 +0530230 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
231 major_version = *(p + 3);
232 minor_version = *(p + 4);
nxpandroidc7611652015-09-23 16:42:05 +0530233
nxpandroid8f6d0532017-07-12 18:25:30 +0530234 if ((T4T_DESEV0_MAJOR_VERSION == major_version) &&
235 (T4T_DESEV0_MINOR_VERSION == minor_version)) {
236 p_t4t->card_size = 0xEDE;
237 } else if (major_version >= T4T_DESEV1_MAJOR_VERSION) {
238 p_t4t->card_type = T4T_TYPE_DESFIRE_EV1;
239 switch (*(p + 5)) {
240 case T4T_SIZE_IDENTIFIER_2K:
241 p_t4t->card_size = 2048;
242 break;
243 case T4T_SIZE_IDENTIFIER_4K:
244 p_t4t->card_size = 4096;
245 break;
246 case T4T_SIZE_IDENTIFIER_8K:
247 p_t4t->card_size = 7680;
248 break;
249 default:
250 return false;
nxpandroidc7611652015-09-23 16:42:05 +0530251 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530252 } else {
253 return false;
254 }
nxpandroidc7611652015-09-23 16:42:05 +0530255
nxpandroid8f6d0532017-07-12 18:25:30 +0530256 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530257}
258
259/*******************************************************************************
260**
261** Function rw_t4t_get_uid_details
262**
263** Description Send get uid cmd to peer
264**
nxf24591c1cbeab2018-02-21 17:32:26 +0530265** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530266**
267*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530268static bool rw_t4t_get_uid_details(void) {
269 NFC_HDR* p_c_apdu;
270 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530271
nxpandroid8f6d0532017-07-12 18:25:30 +0530272 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530273
nxpandroid8f6d0532017-07-12 18:25:30 +0530274 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530275 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530276 return false;
277 }
nxpandroidc7611652015-09-23 16:42:05 +0530278
nxpandroid8f6d0532017-07-12 18:25:30 +0530279 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
280 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530281
nxpandroid8f6d0532017-07-12 18:25:30 +0530282 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
283 UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
284 UINT16_TO_BE_STREAM(p, 0x0000);
285 UINT8_TO_BE_FIELD(p, 0x00);
nxpandroidc7611652015-09-23 16:42:05 +0530286
nxpandroid8f6d0532017-07-12 18:25:30 +0530287 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530288
nxpandroid8f6d0532017-07-12 18:25:30 +0530289 if (!rw_t4t_send_to_lower(p_c_apdu)) {
290 return false;
291 }
nxpandroidc7611652015-09-23 16:42:05 +0530292
nxpandroid8f6d0532017-07-12 18:25:30 +0530293 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530294}
295
296/*******************************************************************************
297**
298** Function rw_t4t_create_app
299**
300** Description Send create application cmd to peer
301**
nxf24591c1cbeab2018-02-21 17:32:26 +0530302** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530303**
304*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530305static bool rw_t4t_create_app(void) {
306 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
307 NFC_HDR* p_c_apdu;
308 uint8_t* p;
309 uint8_t df_name[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
nxpandroidcdd30442016-05-27 17:26:18 +0530310
nxpandroid8f6d0532017-07-12 18:25:30 +0530311 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530312
nxpandroid8f6d0532017-07-12 18:25:30 +0530313 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530314 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530315 return false;
316 }
nxpandroidc7611652015-09-23 16:42:05 +0530317
nxpandroid8f6d0532017-07-12 18:25:30 +0530318 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
319 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530320
nxpandroid8f6d0532017-07-12 18:25:30 +0530321 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
322 UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_AID);
323 UINT16_TO_BE_STREAM(p, 0x0000);
324 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
325 UINT8_TO_BE_STREAM(p, (T4T_CMD_MAX_HDR_SIZE + sizeof(df_name) + 2));
326 UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
327 UINT16_TO_BE_STREAM(p, 0x0F21); /*Key settings and no.of keys */
328 UINT16_TO_BE_STREAM(p, 0x05E1); /* ISO file ID */
329 ARRAY_TO_BE_STREAM(p, df_name, (int)sizeof(df_name)); /*DF file name */
330 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
331 p_c_apdu->len = 20;
332 } else {
333 UINT8_TO_BE_STREAM(p, T4T_CMD_MAX_HDR_SIZE);
334 UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
335 UINT16_TO_BE_STREAM(p, 0x0F01); /*Key settings and no.of keys */
336 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
337 p_c_apdu->len = 11;
338 }
nxpandroidc7611652015-09-23 16:42:05 +0530339
nxpandroid8f6d0532017-07-12 18:25:30 +0530340 if (!rw_t4t_send_to_lower(p_c_apdu)) {
341 return false;
342 }
nxpandroidc7611652015-09-23 16:42:05 +0530343
nxpandroid8f6d0532017-07-12 18:25:30 +0530344 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530345}
346
347/*******************************************************************************
348**
349** Function rw_t4t_select_app
350**
351** Description Select application cmd to peer
352**
nxf24591c1cbeab2018-02-21 17:32:26 +0530353** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530354**
355*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530356static bool rw_t4t_select_app(void) {
357 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
358 NFC_HDR* p_c_apdu;
359 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530360
nxpandroid8f6d0532017-07-12 18:25:30 +0530361 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530362
nxpandroid8f6d0532017-07-12 18:25:30 +0530363 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530364 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530365 return false;
366 }
nxpandroidc7611652015-09-23 16:42:05 +0530367
nxpandroid8f6d0532017-07-12 18:25:30 +0530368 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
369 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530370
nxpandroid8f6d0532017-07-12 18:25:30 +0530371 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
372 UINT8_TO_BE_STREAM(p, T4T_CMD_SELECT_APP);
373 UINT16_TO_BE_STREAM(p, 0x0000);
374 UINT8_TO_BE_STREAM(p, 0x03); /* Lc: length of wrapped data */
375 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
376 UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
377 } else {
378 UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
379 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530380
nxpandroid8f6d0532017-07-12 18:25:30 +0530381 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530382
nxpandroid8f6d0532017-07-12 18:25:30 +0530383 p_c_apdu->len = 9;
nxpandroidc7611652015-09-23 16:42:05 +0530384
nxpandroid8f6d0532017-07-12 18:25:30 +0530385 if (!rw_t4t_send_to_lower(p_c_apdu)) {
386 return false;
387 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530388
nxpandroid8f6d0532017-07-12 18:25:30 +0530389 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530390}
391
392/*******************************************************************************
393**
394** Function rw_t4t_create_ccfile
395**
396** Description create capability container file cmd to peer
397**
nxf24591c1cbeab2018-02-21 17:32:26 +0530398** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530399**
400*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530401static bool rw_t4t_create_ccfile(void) {
402 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
403 NFC_HDR* p_c_apdu;
404 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530405
nxpandroid8f6d0532017-07-12 18:25:30 +0530406 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530407
nxpandroid8f6d0532017-07-12 18:25:30 +0530408 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530409 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530410 return false;
411 }
nxpandroidc7611652015-09-23 16:42:05 +0530412
nxpandroid8f6d0532017-07-12 18:25:30 +0530413 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
414 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530415
nxpandroid8f6d0532017-07-12 18:25:30 +0530416 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
417 UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
418 UINT16_TO_BE_STREAM(p, 0x0000);
419 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
420 UINT8_TO_BE_STREAM(p, 0x09); /* Lc: length of wrapped data */
421 UINT8_TO_BE_STREAM(p, 0x01); /* EV1 CC file id */
422 UINT16_TO_BE_STREAM(p, 0x03E1); /* ISO file id */
423 } else {
424 UINT8_TO_BE_STREAM(p, 0x07); /* Lc: length of wrapped data */
425 UINT8_TO_BE_STREAM(p, 0x03); /* DESFire CC file id */
426 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530427
nxpandroid8f6d0532017-07-12 18:25:30 +0530428 UINT8_TO_BE_STREAM(p, 0x00); /* COMM settings */
429 UINT16_TO_BE_STREAM(p, 0xEEEE); /* Access rights */
430 UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set file size */
431 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530432
nxpandroid8f6d0532017-07-12 18:25:30 +0530433 p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
nxpandroidc7611652015-09-23 16:42:05 +0530434
nxpandroid8f6d0532017-07-12 18:25:30 +0530435 if (!rw_t4t_send_to_lower(p_c_apdu)) {
436 return false;
437 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530438
nxpandroid8f6d0532017-07-12 18:25:30 +0530439 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530440}
441
442/*******************************************************************************
443**
444** Function rw_t4t_create_ndef
445**
446** Description creates an ndef file cmd to peer
447**
nxf24591c1cbeab2018-02-21 17:32:26 +0530448** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530449**
450*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530451static bool rw_t4t_create_ndef(void) {
452 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
453 NFC_HDR* p_c_apdu;
454 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530455
nxpandroid8f6d0532017-07-12 18:25:30 +0530456 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530457
nxpandroid8f6d0532017-07-12 18:25:30 +0530458 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530459 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530460 return false;
461 }
nxpandroidc7611652015-09-23 16:42:05 +0530462
nxpandroid8f6d0532017-07-12 18:25:30 +0530463 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
464 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530465
nxpandroid8f6d0532017-07-12 18:25:30 +0530466 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
467 UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
468 UINT16_TO_BE_STREAM(p, 0x0000);
469 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
470 UINT8_TO_BE_STREAM(p, 0x09); /* Lc: length of wrapped data */
471 UINT8_TO_BE_STREAM(p, 0x02); /* DESFEv1 NDEF file id */
472 UINT16_TO_BE_STREAM(p, 0x04E1); /* ISO file id */
473 } else {
474 UINT8_TO_BE_STREAM(p, 0x07);
475 UINT8_TO_BE_STREAM(p, 0x04); /* DESF4 NDEF file id */
476 }
nxpandroidc7611652015-09-23 16:42:05 +0530477
nxpandroid8f6d0532017-07-12 18:25:30 +0530478 UINT8_TO_BE_STREAM(p, 0x00); /* COMM settings */
479 UINT16_TO_BE_STREAM(p, 0xEEEE); /* Access rights */
480 UINT16_TO_STREAM(p, p_t4t->card_size);
481 UINT8_TO_BE_STREAM(p, 0x00); /* Set card size */
482 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530483
nxpandroid8f6d0532017-07-12 18:25:30 +0530484 p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
nxpandroidc7611652015-09-23 16:42:05 +0530485
nxpandroid8f6d0532017-07-12 18:25:30 +0530486 if (!rw_t4t_send_to_lower(p_c_apdu)) {
487 return false;
488 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530489
nxpandroid8f6d0532017-07-12 18:25:30 +0530490 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530491}
492
493/*******************************************************************************
494**
495** Function rw_t4t_write_cc
496**
497** Description sends write cc file cmd to peer
498**
nxf24591c1cbeab2018-02-21 17:32:26 +0530499** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530500**
501*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530502static bool rw_t4t_write_cc(void) {
503 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
504 NFC_HDR* p_c_apdu;
505 uint8_t* p;
506 uint8_t CCFileBytes[] = {0x00, 0x0F, 0x10, 0x00, 0x3B, 0x00, 0x34, 0x04,
507 0x06, 0xE1, 0x04, 0x04, 0x00, 0x00, 0x00};
nxpandroidc7611652015-09-23 16:42:05 +0530508
nxpandroid8f6d0532017-07-12 18:25:30 +0530509 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530510
nxpandroid8f6d0532017-07-12 18:25:30 +0530511 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530512 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530513 return false;
514 }
nxpandroidc7611652015-09-23 16:42:05 +0530515
nxpandroid8f6d0532017-07-12 18:25:30 +0530516 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
517 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530518
nxpandroid8f6d0532017-07-12 18:25:30 +0530519 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
520 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
521 UINT16_TO_BE_STREAM(p, 0x0000);
522 UINT8_TO_BE_STREAM(p, 0x16); /* Lc: length of wrapped data */
523 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
524 CCFileBytes[2] = 0x20;
525 CCFileBytes[11] = p_t4t->card_size >> 8;
526 CCFileBytes[12] = (uint8_t)p_t4t->card_size;
527 UINT8_TO_BE_STREAM(p, 0x01); /* CC file id */
528 } else {
529 UINT8_TO_BE_STREAM(p, 0x03);
530 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530531
nxpandroid8f6d0532017-07-12 18:25:30 +0530532 UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset */
533 UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set available length */
534 ARRAY_TO_BE_STREAM(p, CCFileBytes, (int)sizeof(CCFileBytes));
535 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530536
nxpandroid8f6d0532017-07-12 18:25:30 +0530537 p_c_apdu->len = 28;
nxpandroidc7611652015-09-23 16:42:05 +0530538
nxpandroid8f6d0532017-07-12 18:25:30 +0530539 if (!rw_t4t_send_to_lower(p_c_apdu)) {
540 return false;
541 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530542
nxpandroid8f6d0532017-07-12 18:25:30 +0530543 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530544}
545
546/*******************************************************************************
547**
548** Function rw_t4t_write_ndef
549**
550** Description sends write ndef file cmd to peer
551**
nxf24591c1cbeab2018-02-21 17:32:26 +0530552** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530553**
554*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530555static bool rw_t4t_write_ndef(void) {
556 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
557 NFC_HDR* p_c_apdu;
558 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530559
nxpandroid8f6d0532017-07-12 18:25:30 +0530560 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530561
nxpandroid8f6d0532017-07-12 18:25:30 +0530562 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530563 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530564 return false;
565 }
nxpandroidc7611652015-09-23 16:42:05 +0530566
nxpandroid8f6d0532017-07-12 18:25:30 +0530567 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
568 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530569
nxpandroid8f6d0532017-07-12 18:25:30 +0530570 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
571 UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
572 UINT16_TO_BE_STREAM(p, 0x0000);
573 UINT8_TO_BE_STREAM(p, 0x09); /* Lc: length of wrapped data */
574 if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
575 UINT8_TO_BE_STREAM(p, 0x02); /* DESFEv1 Ndef file id */
576 } else {
577 UINT8_TO_BE_STREAM(p, 0x04);
578 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530579
nxpandroid8f6d0532017-07-12 18:25:30 +0530580 UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset */
581 UINT24_TO_BE_STREAM(p, 0x020000); /* Set available length */
582 UINT16_TO_BE_STREAM(p, 0x0000); /* Ndef file bytes */
583 UINT8_TO_BE_STREAM(p, 0x00); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530584
nxpandroid8f6d0532017-07-12 18:25:30 +0530585 p_c_apdu->len = 15;
nxpandroidc7611652015-09-23 16:42:05 +0530586
nxpandroid8f6d0532017-07-12 18:25:30 +0530587 if (!rw_t4t_send_to_lower(p_c_apdu)) {
588 return false;
589 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530590
nxpandroid8f6d0532017-07-12 18:25:30 +0530591 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530592}
nxpandroidc7611652015-09-23 16:42:05 +0530593
nxpandroidc7611652015-09-23 16:42:05 +0530594/*******************************************************************************
595**
596** Function rw_t4t_select_file
597**
598** Description Send Select Command (by File ID) to peer
599**
nxf24591c1cbeab2018-02-21 17:32:26 +0530600** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530601**
602*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530603static bool rw_t4t_select_file(uint16_t file_id) {
604 NFC_HDR* p_c_apdu;
605 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530606
nxf24591c1cbeab2018-02-21 17:32:26 +0530607 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("File ID:0x%04X", file_id);
nxpandroidc7611652015-09-23 16:42:05 +0530608
nxpandroid8f6d0532017-07-12 18:25:30 +0530609 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530610
nxpandroid8f6d0532017-07-12 18:25:30 +0530611 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530612 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530613 return false;
614 }
nxpandroidc7611652015-09-23 16:42:05 +0530615
nxpandroid8f6d0532017-07-12 18:25:30 +0530616 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
617 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530618
nxpandroid8f6d0532017-07-12 18:25:30 +0530619 UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
620 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
621 UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_FILE_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530622
nxpandroid8f6d0532017-07-12 18:25:30 +0530623 /* if current version mapping is V2.0 */
624 if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0) {
625 UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
626 } else /* version 1.0 */
627 {
628 UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
629 }
nxpandroidc7611652015-09-23 16:42:05 +0530630
nxpandroid8f6d0532017-07-12 18:25:30 +0530631 UINT8_TO_BE_STREAM(p, T4T_FILE_ID_SIZE);
632 UINT16_TO_BE_STREAM(p, file_id);
nxpandroidc7611652015-09-23 16:42:05 +0530633
nxpandroid8f6d0532017-07-12 18:25:30 +0530634 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530635
nxpandroid8f6d0532017-07-12 18:25:30 +0530636 if (!rw_t4t_send_to_lower(p_c_apdu)) {
637 return false;
638 }
nxpandroidc7611652015-09-23 16:42:05 +0530639
nxpandroid8f6d0532017-07-12 18:25:30 +0530640 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530641}
642
643/*******************************************************************************
644**
645** Function rw_t4t_read_file
646**
647** Description Send ReadBinary Command to peer
648**
nxf24591c1cbeab2018-02-21 17:32:26 +0530649** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530650**
651*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530652static bool rw_t4t_read_file(uint16_t offset, uint16_t length,
653 bool is_continue) {
654 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
655 NFC_HDR* p_c_apdu;
656 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530657
nxf24591c1cbeab2018-02-21 17:32:26 +0530658 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
659 "offset:%d, length:%d, is_continue:%d, ", offset, length, is_continue);
nxpandroidc7611652015-09-23 16:42:05 +0530660
nxpandroid8f6d0532017-07-12 18:25:30 +0530661 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530662
nxpandroid8f6d0532017-07-12 18:25:30 +0530663 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530664 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530665 return false;
666 }
nxpandroidc7611652015-09-23 16:42:05 +0530667
nxpandroid8f6d0532017-07-12 18:25:30 +0530668 /* if this is the first reading */
669 if (is_continue == false) {
670 /* initialise starting offset and total length */
671 /* these will be updated when receiving response */
672 p_t4t->rw_offset = offset;
673 p_t4t->rw_length = length;
674 }
nxpandroidc7611652015-09-23 16:42:05 +0530675
nxpandroid8f6d0532017-07-12 18:25:30 +0530676 /* adjust reading length if payload is bigger than max size per single command
677 */
678 if (length > p_t4t->max_read_size) {
679 length = (uint8_t)(p_t4t->max_read_size);
680 }
nxpandroidc7611652015-09-23 16:42:05 +0530681
nxpandroid8f6d0532017-07-12 18:25:30 +0530682 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
683 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530684
nxpandroid8f6d0532017-07-12 18:25:30 +0530685 UINT8_TO_BE_STREAM(p, (T4T_CMD_CLASS | rw_cb.tcb.t4t.channel));
686 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_READ_BINARY);
687 UINT16_TO_BE_STREAM(p, offset);
688 UINT8_TO_BE_STREAM(p, length); /* Le */
nxpandroidc7611652015-09-23 16:42:05 +0530689
nxpandroid8f6d0532017-07-12 18:25:30 +0530690 p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */
nxpandroidc7611652015-09-23 16:42:05 +0530691
nxpandroid8f6d0532017-07-12 18:25:30 +0530692 if (!rw_t4t_send_to_lower(p_c_apdu)) {
693 return false;
694 }
nxpandroidc7611652015-09-23 16:42:05 +0530695
nxpandroid8f6d0532017-07-12 18:25:30 +0530696 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530697}
698
699/*******************************************************************************
700**
701** Function rw_t4t_update_nlen
702**
703** Description Send UpdateBinary Command to update NLEN to peer
704**
nxf24591c1cbeab2018-02-21 17:32:26 +0530705** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530706**
707*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530708static bool rw_t4t_update_nlen(uint16_t ndef_len) {
709 NFC_HDR* p_c_apdu;
710 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530711
nxf24591c1cbeab2018-02-21 17:32:26 +0530712 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("NLEN:%d", ndef_len);
nxpandroidc7611652015-09-23 16:42:05 +0530713
nxpandroid8f6d0532017-07-12 18:25:30 +0530714 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530715
nxpandroid8f6d0532017-07-12 18:25:30 +0530716 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530717 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530718 return false;
719 }
nxpandroidc7611652015-09-23 16:42:05 +0530720
nxpandroid8f6d0532017-07-12 18:25:30 +0530721 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
722 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530723
nxpandroid8f6d0532017-07-12 18:25:30 +0530724 UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
725 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
726 UINT16_TO_BE_STREAM(p, 0x0000); /* offset for NLEN */
727 UINT8_TO_BE_STREAM(p, T4T_FILE_LENGTH_SIZE);
728 UINT16_TO_BE_STREAM(p, ndef_len);
nxpandroidc7611652015-09-23 16:42:05 +0530729
nxpandroid8f6d0532017-07-12 18:25:30 +0530730 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +0530731
nxpandroid8f6d0532017-07-12 18:25:30 +0530732 if (!rw_t4t_send_to_lower(p_c_apdu)) {
733 return false;
734 }
nxpandroidc7611652015-09-23 16:42:05 +0530735
nxpandroid8f6d0532017-07-12 18:25:30 +0530736 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530737}
738
739/*******************************************************************************
740**
741** Function rw_t4t_update_file
742**
743** Description Send UpdateBinary Command to peer
744**
nxf24591c1cbeab2018-02-21 17:32:26 +0530745** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530746**
747*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530748static bool rw_t4t_update_file(void) {
749 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
750 NFC_HDR* p_c_apdu;
751 uint8_t* p;
752 uint16_t length;
nxpandroidc7611652015-09-23 16:42:05 +0530753
nxf24591c1cbeab2018-02-21 17:32:26 +0530754 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
755 "rw_offset:%d, rw_length:%d", p_t4t->rw_offset, p_t4t->rw_length);
nxpandroidc7611652015-09-23 16:42:05 +0530756
nxpandroid8f6d0532017-07-12 18:25:30 +0530757 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530758
nxpandroid8f6d0532017-07-12 18:25:30 +0530759 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530760 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530761 return false;
762 }
nxpandroidc7611652015-09-23 16:42:05 +0530763
nxpandroid8f6d0532017-07-12 18:25:30 +0530764 /* try to send all of remaining data */
765 length = p_t4t->rw_length;
nxpandroidc7611652015-09-23 16:42:05 +0530766
nxpandroid8f6d0532017-07-12 18:25:30 +0530767 /* adjust updating length if payload is bigger than max size per single
768 * command */
769 if (length > p_t4t->max_update_size) {
770 length = (uint8_t)(p_t4t->max_update_size);
771 }
nxpandroidc7611652015-09-23 16:42:05 +0530772
nxpandroid8f6d0532017-07-12 18:25:30 +0530773 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
774 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530775
nxpandroid8f6d0532017-07-12 18:25:30 +0530776 UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
777 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
778 UINT16_TO_BE_STREAM(p, p_t4t->rw_offset);
779 UINT8_TO_BE_STREAM(p, length);
nxpandroidc7611652015-09-23 16:42:05 +0530780
nxpandroid8f6d0532017-07-12 18:25:30 +0530781 memcpy(p, p_t4t->p_update_data, length);
nxpandroidc7611652015-09-23 16:42:05 +0530782
nxpandroid8f6d0532017-07-12 18:25:30 +0530783 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;
nxpandroidc7611652015-09-23 16:42:05 +0530784
nxpandroid8f6d0532017-07-12 18:25:30 +0530785 if (!rw_t4t_send_to_lower(p_c_apdu)) {
786 return false;
787 }
nxpandroidc7611652015-09-23 16:42:05 +0530788
nxpandroid8f6d0532017-07-12 18:25:30 +0530789 /* adjust offset, length and pointer for remaining data */
790 p_t4t->rw_offset += length;
791 p_t4t->rw_length -= length;
792 p_t4t->p_update_data += length;
nxpandroidc7611652015-09-23 16:42:05 +0530793
nxpandroid8f6d0532017-07-12 18:25:30 +0530794 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530795}
796
797/*******************************************************************************
798**
799** Function rw_t4t_update_cc_to_readonly
800**
801** Description Send UpdateBinary Command for changing Write access
802**
nxf24591c1cbeab2018-02-21 17:32:26 +0530803** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530804**
805*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530806static bool rw_t4t_update_cc_to_readonly(void) {
807 NFC_HDR* p_c_apdu;
808 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530809
nxf24591c1cbeab2018-02-21 17:32:26 +0530810 DLOG_IF(INFO, nfc_debug_enabled)
811 << StringPrintf("Remove Write access from CC");
nxpandroidc7611652015-09-23 16:42:05 +0530812
nxpandroid8f6d0532017-07-12 18:25:30 +0530813 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530814
nxpandroid8f6d0532017-07-12 18:25:30 +0530815 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530816 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530817 return false;
818 }
nxpandroidc7611652015-09-23 16:42:05 +0530819
nxpandroid8f6d0532017-07-12 18:25:30 +0530820 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
821 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530822
nxpandroid8f6d0532017-07-12 18:25:30 +0530823 /* Add Command Header */
824 UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
825 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
826 UINT16_TO_BE_STREAM(
827 p, (T4T_FC_TLV_OFFSET_IN_CC +
828 T4T_FC_WRITE_ACCESS_OFFSET_IN_TLV)); /* Offset for Read Write access
829 byte of CC */
830 UINT8_TO_BE_STREAM(
831 p, 1); /* Length of write access field in cc interms of bytes */
nxpandroidc7611652015-09-23 16:42:05 +0530832
nxpandroid8f6d0532017-07-12 18:25:30 +0530833 /* Remove Write access */
834 UINT8_TO_BE_STREAM(p, T4T_FC_NO_WRITE_ACCESS);
nxpandroidc7611652015-09-23 16:42:05 +0530835
nxpandroid8f6d0532017-07-12 18:25:30 +0530836 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + 1;
nxpandroidc7611652015-09-23 16:42:05 +0530837
nxpandroid8f6d0532017-07-12 18:25:30 +0530838 if (!rw_t4t_send_to_lower(p_c_apdu)) {
839 return false;
840 }
nxpandroidc7611652015-09-23 16:42:05 +0530841
nxpandroid8f6d0532017-07-12 18:25:30 +0530842 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530843}
844
845/*******************************************************************************
846**
847** Function rw_t4t_select_application
848**
849** Description Select Application
850**
851** NDEF Tag Application Select - C-APDU
852**
853** CLA INS P1 P2 Lc Data(AID) Le
854** V1.0: 00 A4 04 00 07 D2760000850100 -
855** V2.0: 00 A4 04 00 07 D2760000850101 00
856**
nxf24591c1cbeab2018-02-21 17:32:26 +0530857** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530858**
859*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530860static bool rw_t4t_select_application(uint8_t version) {
861 NFC_HDR* p_c_apdu;
862 uint8_t* p;
nxpandroidc7611652015-09-23 16:42:05 +0530863
nxf24591c1cbeab2018-02-21 17:32:26 +0530864 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("version:0x%X", version);
nxpandroidc7611652015-09-23 16:42:05 +0530865
nxpandroid8f6d0532017-07-12 18:25:30 +0530866 p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
nxpandroidc7611652015-09-23 16:42:05 +0530867
nxpandroid8f6d0532017-07-12 18:25:30 +0530868 if (!p_c_apdu) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530869 LOG(ERROR) << StringPrintf("Cannot allocate buffer");
nxpandroid8f6d0532017-07-12 18:25:30 +0530870 return false;
871 }
nxpandroidc7611652015-09-23 16:42:05 +0530872
nxpandroid8f6d0532017-07-12 18:25:30 +0530873 p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
874 p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +0530875
nxpandroid8f6d0532017-07-12 18:25:30 +0530876 UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
877 UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
878 UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_NAME);
879 UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
nxpandroidc7611652015-09-23 16:42:05 +0530880
nxpandroid8f6d0532017-07-12 18:25:30 +0530881 if (version == T4T_VERSION_1_0) /* this is for V1.0 */
882 {
883 UINT8_TO_BE_STREAM(p, T4T_V10_NDEF_TAG_AID_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530884
nxpandroid8f6d0532017-07-12 18:25:30 +0530885 memcpy(p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530886
nxpandroid8f6d0532017-07-12 18:25:30 +0530887 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN;
888 } else if (version == T4T_VERSION_2_0) /* this is for V2.0 */
889 {
890 UINT8_TO_BE_STREAM(p, T4T_V20_NDEF_TAG_AID_LEN);
nxpandroidc7611652015-09-23 16:42:05 +0530891
nxpandroid8f6d0532017-07-12 18:25:30 +0530892 memcpy(p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN);
893 p += T4T_V20_NDEF_TAG_AID_LEN;
nxpandroidc7611652015-09-23 16:42:05 +0530894
nxpandroid8f6d0532017-07-12 18:25:30 +0530895 UINT8_TO_BE_STREAM(p, 0x00); /* Le set to 0x00 */
nxpandroidc7611652015-09-23 16:42:05 +0530896
nxpandroid8f6d0532017-07-12 18:25:30 +0530897 p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1;
898 } else {
899 return false;
900 }
nxpandroidc7611652015-09-23 16:42:05 +0530901
nxpandroid8f6d0532017-07-12 18:25:30 +0530902 if (!rw_t4t_send_to_lower(p_c_apdu)) {
903 return false;
904 }
nxpandroidc7611652015-09-23 16:42:05 +0530905
nxpandroid8f6d0532017-07-12 18:25:30 +0530906 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530907}
908
909/*******************************************************************************
910**
911** Function rw_t4t_validate_cc_file
912**
913** Description Validate CC file and mandatory NDEF TLV
914**
nxf24591c1cbeab2018-02-21 17:32:26 +0530915** Returns TRUE if success
nxpandroidc7611652015-09-23 16:42:05 +0530916**
917*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530918static bool rw_t4t_validate_cc_file(void) {
919 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
nxpandroidc7611652015-09-23 16:42:05 +0530920
nxf24591c1cbeab2018-02-21 17:32:26 +0530921 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +0530922
nxpandroid8f6d0532017-07-12 18:25:30 +0530923 if (p_t4t->cc_file.cclen < T4T_CC_FILE_MIN_LEN) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530924 LOG(ERROR) << StringPrintf("CCLEN (%d) is too short", p_t4t->cc_file.cclen);
nxpandroid8f6d0532017-07-12 18:25:30 +0530925 return false;
926 }
nxpandroidc7611652015-09-23 16:42:05 +0530927
nxpandroid8f6d0532017-07-12 18:25:30 +0530928 if (T4T_GET_MAJOR_VERSION(p_t4t->cc_file.version) !=
929 T4T_GET_MAJOR_VERSION(p_t4t->version)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530930 LOG(ERROR) << StringPrintf(
931 "Peer version (0x%02X) is matched to ours "
nxpandroid8f6d0532017-07-12 18:25:30 +0530932 "(0x%02X)",
933 p_t4t->cc_file.version, p_t4t->version);
934 return false;
935 }
nxpandroidc7611652015-09-23 16:42:05 +0530936
nxpandroid8f6d0532017-07-12 18:25:30 +0530937 if (p_t4t->cc_file.max_le < 0x000F) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530938 LOG(ERROR) << StringPrintf("MaxLe (%d) is too small",
939 p_t4t->cc_file.max_le);
nxpandroid8f6d0532017-07-12 18:25:30 +0530940 return false;
941 }
nxpandroidc7611652015-09-23 16:42:05 +0530942
nxpandroid8f6d0532017-07-12 18:25:30 +0530943 if (p_t4t->cc_file.max_lc < 0x0001) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530944 LOG(ERROR) << StringPrintf("MaxLc (%d) is too small",
945 p_t4t->cc_file.max_lc);
nxpandroid8f6d0532017-07-12 18:25:30 +0530946 return false;
947 }
nxpandroidc7611652015-09-23 16:42:05 +0530948
nxpandroid8f6d0532017-07-12 18:25:30 +0530949 if ((p_t4t->cc_file.ndef_fc.file_id == T4T_CC_FILE_ID) ||
950 (p_t4t->cc_file.ndef_fc.file_id == 0xE102) ||
951 (p_t4t->cc_file.ndef_fc.file_id == 0xE103) ||
952 ((p_t4t->cc_file.ndef_fc.file_id == 0x0000) &&
953 (p_t4t->cc_file.version == 0x20)) ||
954 (p_t4t->cc_file.ndef_fc.file_id == 0x3F00) ||
955 (p_t4t->cc_file.ndef_fc.file_id == 0x3FFF) ||
956 (p_t4t->cc_file.ndef_fc.file_id == 0xFFFF)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530957 LOG(ERROR) << StringPrintf("File ID (0x%04X) is invalid",
958 p_t4t->cc_file.ndef_fc.file_id);
nxpandroid8f6d0532017-07-12 18:25:30 +0530959 return false;
960 }
nxpandroidc7611652015-09-23 16:42:05 +0530961
nxpandroid8f6d0532017-07-12 18:25:30 +0530962 if ((p_t4t->cc_file.ndef_fc.max_file_size < 0x0005) ||
963 (p_t4t->cc_file.ndef_fc.max_file_size == 0xFFFF)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530964 LOG(ERROR) << StringPrintf("max_file_size (%d) is reserved",
965 p_t4t->cc_file.ndef_fc.max_file_size);
nxpandroid8f6d0532017-07-12 18:25:30 +0530966 return false;
967 }
nxpandroidc7611652015-09-23 16:42:05 +0530968
nxpandroid8f6d0532017-07-12 18:25:30 +0530969 if (p_t4t->cc_file.ndef_fc.read_access != T4T_FC_READ_ACCESS) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530970 LOG(ERROR) << StringPrintf("Read Access (0x%02X) is invalid",
971 p_t4t->cc_file.ndef_fc.read_access);
nxpandroid8f6d0532017-07-12 18:25:30 +0530972 return false;
973 }
nxpandroidc7611652015-09-23 16:42:05 +0530974
nxpandroid8f6d0532017-07-12 18:25:30 +0530975 if ((p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) &&
976 (p_t4t->cc_file.ndef_fc.write_access < T4T_FC_WRITE_ACCESS_PROP_START)) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530977 LOG(ERROR) << StringPrintf("Write Access (0x%02X) is invalid",
978 p_t4t->cc_file.ndef_fc.write_access);
nxpandroid8f6d0532017-07-12 18:25:30 +0530979 return false;
980 }
nxpandroidc7611652015-09-23 16:42:05 +0530981
nxpandroid8f6d0532017-07-12 18:25:30 +0530982 return true;
nxpandroidc7611652015-09-23 16:42:05 +0530983}
984
985/*******************************************************************************
986**
987** Function rw_t4t_handle_error
988**
989** Description notify error to application and clean up
990**
991** Returns none
992**
993*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530994static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2) {
995 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
996 tRW_DATA rw_data;
997 tRW_EVENT event;
nxpandroidc7611652015-09-23 16:42:05 +0530998
nxf24591c1cbeab2018-02-21 17:32:26 +0530999 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1000 "status:0x%02X, sw1:0x%02X, sw2:0x%02X, "
nxpandroid8f6d0532017-07-12 18:25:30 +05301001 "state:0x%X",
1002 status, sw1, sw2, p_t4t->state);
nxpandroidc7611652015-09-23 16:42:05 +05301003
nxpandroid8f6d0532017-07-12 18:25:30 +05301004 nfc_stop_quick_timer(&p_t4t->timer);
nxpandroidc7611652015-09-23 16:42:05 +05301005
nxpandroid8f6d0532017-07-12 18:25:30 +05301006 if (rw_cb.p_cback) {
1007 rw_data.status = status;
nxpandroidc7611652015-09-23 16:42:05 +05301008
nxpandroid8f6d0532017-07-12 18:25:30 +05301009 rw_data.t4t_sw.sw1 = sw1;
1010 rw_data.t4t_sw.sw2 = sw2;
nxpandroidc7611652015-09-23 16:42:05 +05301011
nxpandroid8f6d0532017-07-12 18:25:30 +05301012 switch (p_t4t->state) {
1013 case RW_T4T_STATE_DETECT_NDEF:
1014 rw_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
1015 event = RW_T4T_NDEF_DETECT_EVT;
1016 break;
nxpandroidc7611652015-09-23 16:42:05 +05301017
nxpandroid8f6d0532017-07-12 18:25:30 +05301018 case RW_T4T_STATE_READ_NDEF:
1019 event = RW_T4T_NDEF_READ_FAIL_EVT;
1020 break;
nxpandroidc7611652015-09-23 16:42:05 +05301021
nxpandroid8f6d0532017-07-12 18:25:30 +05301022 case RW_T4T_STATE_UPDATE_NDEF:
1023 event = RW_T4T_NDEF_UPDATE_FAIL_EVT;
1024 break;
nxpandroidc7611652015-09-23 16:42:05 +05301025
nxpandroid8f6d0532017-07-12 18:25:30 +05301026 case RW_T4T_STATE_PRESENCE_CHECK:
1027 event = RW_T4T_PRESENCE_CHECK_EVT;
1028 rw_data.status = NFC_STATUS_FAILED;
1029 break;
nxpandroidc7611652015-09-23 16:42:05 +05301030
nxpandroid8f6d0532017-07-12 18:25:30 +05301031 case RW_T4T_STATE_SET_READ_ONLY:
1032 event = RW_T4T_SET_TO_RO_EVT;
1033 break;
nxpandroidc7611652015-09-23 16:42:05 +05301034
nxpandroid8f6d0532017-07-12 18:25:30 +05301035 case RW_T4T_STATE_NDEF_FORMAT:
1036 event = RW_T4T_NDEF_FORMAT_CPLT_EVT;
1037 rw_data.status = NFC_STATUS_FAILED;
1038 break;
nxf24591c1cbeab2018-02-21 17:32:26 +05301039
nxpandroid8f6d0532017-07-12 18:25:30 +05301040 default:
1041 event = RW_T4T_MAX_EVT;
1042 break;
nxpandroidc7611652015-09-23 16:42:05 +05301043 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301044
1045 p_t4t->state = RW_T4T_STATE_IDLE;
1046
1047 if (event != RW_T4T_MAX_EVT) {
1048 (*(rw_cb.p_cback))(event, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301049 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301050 } else {
1051 p_t4t->state = RW_T4T_STATE_IDLE;
1052 }
nxpandroidc7611652015-09-23 16:42:05 +05301053}
nxpandroidcdd30442016-05-27 17:26:18 +05301054
nxpandroidc7611652015-09-23 16:42:05 +05301055/*******************************************************************************
1056**
1057** Function rw_t4t_sm_ndef_format
1058**
1059** Description State machine for NDEF format procedure
1060**
1061** Returns none
1062**
1063*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301064static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu) {
1065 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
nxf24591c1cbeab2018-02-21 17:32:26 +05301066 uint8_t* p;
1067 uint16_t status_words;
nxpandroid8f6d0532017-07-12 18:25:30 +05301068 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301069
nxf24591c1cbeab2018-02-21 17:32:26 +05301070 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1071 "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1072 p_t4t->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301073
nxpandroid8f6d0532017-07-12 18:25:30 +05301074 /* get status words */
1075 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301076
nxpandroid8f6d0532017-07-12 18:25:30 +05301077 switch (p_t4t->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301078 case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
nxpandroid8f6d0532017-07-12 18:25:30 +05301079 p += (p_r_apdu->len - 1);
1080 if (*(p) == T4T_ADDI_FRAME_RESP) {
1081 if (!rw_t4t_get_sw_version()) {
1082 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1083 } else {
1084 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION;
nxpandroidc7611652015-09-23 16:42:05 +05301085 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301086 } else {
1087 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1088 }
1089 break;
nxpandroidc7611652015-09-23 16:42:05 +05301090
1091 case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
nxpandroid8f6d0532017-07-12 18:25:30 +05301092 p += (p_r_apdu->len - 1);
1093 if (*(p) == T4T_ADDI_FRAME_RESP) {
1094 if (!rw_t4t_update_version_details(p_r_apdu)) {
1095 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
nxpandroidc7611652015-09-23 16:42:05 +05301096 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301097
nxpandroid8f6d0532017-07-12 18:25:30 +05301098 if (!rw_t4t_get_uid_details()) {
1099 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
nxpandroidc7611652015-09-23 16:42:05 +05301100 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301101
nxpandroid8f6d0532017-07-12 18:25:30 +05301102 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_UID;
1103 } else {
1104 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1105 }
1106 break;
nxpandroidc7611652015-09-23 16:42:05 +05301107
1108 case RW_T4T_SUBSTATE_WAIT_GET_UID:
nxpandroid8f6d0532017-07-12 18:25:30 +05301109 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1110 BE_STREAM_TO_UINT16(status_words, p);
1111 if (status_words != 0x9100) {
1112 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1113 } else {
1114 if (!rw_t4t_create_app()) {
1115 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1116 } else {
1117 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_APP;
nxpandroidc7611652015-09-23 16:42:05 +05301118 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301119 }
1120 break;
nxpandroidc7611652015-09-23 16:42:05 +05301121
1122 case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
nxpandroid8f6d0532017-07-12 18:25:30 +05301123 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1124 BE_STREAM_TO_UINT16(status_words, p);
1125 if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1126 {
1127 status_words = 0x9100;
1128 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301129
nxpandroid8f6d0532017-07-12 18:25:30 +05301130 if (status_words != 0x9100) {
1131 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1132 } else {
1133 if (!rw_t4t_select_app()) {
1134 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1135 } else {
1136 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
nxpandroidc7611652015-09-23 16:42:05 +05301137 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301138 }
1139 break;
nxpandroidc7611652015-09-23 16:42:05 +05301140
1141 case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
nxpandroid8f6d0532017-07-12 18:25:30 +05301142 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1143 BE_STREAM_TO_UINT16(status_words, p);
1144 if (status_words != 0x9100) {
1145 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1146 } else {
1147 if (!rw_t4t_create_ccfile()) {
1148 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1149 } else {
1150 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_CC;
nxpandroidc7611652015-09-23 16:42:05 +05301151 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301152 }
1153 break;
nxpandroidc7611652015-09-23 16:42:05 +05301154
1155 case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
nxpandroid8f6d0532017-07-12 18:25:30 +05301156 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1157 BE_STREAM_TO_UINT16(status_words, p);
1158 if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1159 {
1160 status_words = 0x9100;
1161 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301162
nxpandroid8f6d0532017-07-12 18:25:30 +05301163 if (status_words != 0x9100) {
1164 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1165 } else {
1166 if (!rw_t4t_create_ndef()) {
1167 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1168 } else {
1169 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_NDEF;
nxpandroidc7611652015-09-23 16:42:05 +05301170 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301171 }
1172 break;
nxpandroidc7611652015-09-23 16:42:05 +05301173
1174 case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05301175 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1176 BE_STREAM_TO_UINT16(status_words, p);
1177 if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
1178 {
1179 status_words = 0x9100;
1180 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301181
nxpandroid8f6d0532017-07-12 18:25:30 +05301182 if (status_words != 0x9100) {
1183 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1184 } else {
1185 if (!rw_t4t_write_cc()) {
1186 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1187 } else {
1188 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_CC;
nxpandroidc7611652015-09-23 16:42:05 +05301189 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301190 }
1191 break;
nxpandroidc7611652015-09-23 16:42:05 +05301192
1193 case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
nxpandroid8f6d0532017-07-12 18:25:30 +05301194 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1195 BE_STREAM_TO_UINT16(status_words, p);
1196 if (status_words != 0x9100) {
1197 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1198 } else {
1199 if (!rw_t4t_write_ndef()) {
1200 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1201 } else {
1202 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_NDEF;
nxpandroidc7611652015-09-23 16:42:05 +05301203 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301204 }
1205 break;
nxpandroidc7611652015-09-23 16:42:05 +05301206
1207 case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05301208 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1209 BE_STREAM_TO_UINT16(status_words, p);
1210 if (status_words != 0x9100) {
1211 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1212 } else {
1213 p_t4t->state = RW_T4T_STATE_IDLE;
1214 if (rw_cb.p_cback) {
1215 rw_data.ndef.status = NFC_STATUS_OK;
1216 rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
1217 rw_data.ndef.max_size = p_t4t->card_size;
1218 rw_data.ndef.cur_size = 0x00;
nxpandroidc7611652015-09-23 16:42:05 +05301219
nxpandroid8f6d0532017-07-12 18:25:30 +05301220 (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301221
nxf24591c1cbeab2018-02-21 17:32:26 +05301222 DLOG_IF(INFO, nfc_debug_enabled)
1223 << StringPrintf("Sent RW_T4T_NDEF_FORMAT_CPLT_EVT");
nxpandroidc7611652015-09-23 16:42:05 +05301224 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301225 }
1226 break;
nxpandroidc7611652015-09-23 16:42:05 +05301227
1228 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301229 LOG(ERROR) << StringPrintf("unknown sub_state=%d", p_t4t->sub_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301230 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1231 break;
1232 }
nxpandroidc7611652015-09-23 16:42:05 +05301233}
nxpandroidc7611652015-09-23 16:42:05 +05301234
nxpandroidc7611652015-09-23 16:42:05 +05301235/*******************************************************************************
1236**
1237** Function rw_t4t_sm_detect_ndef
1238**
1239** Description State machine for NDEF detection procedure
1240**
1241** Returns none
1242**
1243*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301244static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu) {
1245 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
nxf24591c1cbeab2018-02-21 17:32:26 +05301246 uint8_t *p, type, length;
nxpandroid8f6d0532017-07-12 18:25:30 +05301247 uint16_t status_words, nlen;
1248 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301249
nxf24591c1cbeab2018-02-21 17:32:26 +05301250 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1251 "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1252 p_t4t->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301253
nxpandroid8f6d0532017-07-12 18:25:30 +05301254 /* get status words */
1255 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1256 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1257 BE_STREAM_TO_UINT16(status_words, p);
nxpandroidc7611652015-09-23 16:42:05 +05301258
nxpandroid8f6d0532017-07-12 18:25:30 +05301259 if (status_words != T4T_RSP_CMD_CMPLTED) {
1260 /* try V1.0 after failing of V2.0 */
1261 if ((p_t4t->sub_state == RW_T4T_SUBSTATE_WAIT_SELECT_APP) &&
1262 (p_t4t->version == T4T_VERSION_2_0)) {
1263 p_t4t->version = T4T_VERSION_1_0;
nxpandroidc7611652015-09-23 16:42:05 +05301264
nxf24591c1cbeab2018-02-21 17:32:26 +05301265 DLOG_IF(INFO, nfc_debug_enabled)
1266 << StringPrintf("retry with version=0x%02X", p_t4t->version);
nxpandroidc7611652015-09-23 16:42:05 +05301267
nxpandroid8f6d0532017-07-12 18:25:30 +05301268 if (!rw_t4t_select_application(T4T_VERSION_1_0)) {
1269 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1270 }
1271 return;
nxpandroidc7611652015-09-23 16:42:05 +05301272 }
1273
nxpandroid8f6d0532017-07-12 18:25:30 +05301274 p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1275 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1276 return;
1277 }
1278
1279 switch (p_t4t->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301280 case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
1281
nxpandroid8f6d0532017-07-12 18:25:30 +05301282 /* NDEF Tag application has been selected then select CC file */
1283 if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
1284 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1285 } else {
1286 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
1287 }
1288 break;
nxpandroidc7611652015-09-23 16:42:05 +05301289
1290 case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
1291
nxpandroid8f6d0532017-07-12 18:25:30 +05301292 /* CC file has been selected then read mandatory part of CC file */
1293 if (!rw_t4t_read_file(0x00, T4T_CC_FILE_MIN_LEN, false)) {
1294 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1295 } else {
1296 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CC_FILE;
1297 }
1298 break;
nxpandroidc7611652015-09-23 16:42:05 +05301299
1300 case RW_T4T_SUBSTATE_WAIT_CC_FILE:
1301
nxpandroid8f6d0532017-07-12 18:25:30 +05301302 /* CC file has been read then validate and select mandatory NDEF file */
1303 if (p_r_apdu->len >= T4T_CC_FILE_MIN_LEN + T4T_RSP_STATUS_WORDS_SIZE) {
1304 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
nxpandroidc7611652015-09-23 16:42:05 +05301305
nxpandroid8f6d0532017-07-12 18:25:30 +05301306 BE_STREAM_TO_UINT16(p_t4t->cc_file.cclen, p);
1307 BE_STREAM_TO_UINT8(p_t4t->cc_file.version, p);
1308 BE_STREAM_TO_UINT16(p_t4t->cc_file.max_le, p);
1309 BE_STREAM_TO_UINT16(p_t4t->cc_file.max_lc, p);
nxpandroidc7611652015-09-23 16:42:05 +05301310
nxpandroid8f6d0532017-07-12 18:25:30 +05301311 BE_STREAM_TO_UINT8(type, p);
1312 BE_STREAM_TO_UINT8(length, p);
nxpandroidc7611652015-09-23 16:42:05 +05301313
nxpandroid8f6d0532017-07-12 18:25:30 +05301314 if ((type == T4T_NDEF_FILE_CONTROL_TYPE) &&
1315 (length == T4T_FILE_CONTROL_LENGTH)) {
1316 BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.file_id, p);
1317 BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.max_file_size, p);
1318 BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.read_access, p);
1319 BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.write_access, p);
nxpandroidc7611652015-09-23 16:42:05 +05301320
nxf24591c1cbeab2018-02-21 17:32:26 +05301321 DLOG_IF(INFO, nfc_debug_enabled)
1322 << StringPrintf("Capability Container (CC) file");
1323 DLOG_IF(INFO, nfc_debug_enabled)
1324 << StringPrintf(" CCLEN: 0x%04X", p_t4t->cc_file.cclen);
1325 DLOG_IF(INFO, nfc_debug_enabled)
1326 << StringPrintf(" Version:0x%02X", p_t4t->cc_file.version);
1327 DLOG_IF(INFO, nfc_debug_enabled)
1328 << StringPrintf(" MaxLe: 0x%04X", p_t4t->cc_file.max_le);
1329 DLOG_IF(INFO, nfc_debug_enabled)
1330 << StringPrintf(" MaxLc: 0x%04X", p_t4t->cc_file.max_lc);
1331 DLOG_IF(INFO, nfc_debug_enabled)
1332 << StringPrintf(" NDEF File Control TLV");
1333 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1334 " FileID: 0x%04X", p_t4t->cc_file.ndef_fc.file_id);
1335 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1336 " MaxFileSize: 0x%04X", p_t4t->cc_file.ndef_fc.max_file_size);
1337 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1338 " ReadAccess: 0x%02X", p_t4t->cc_file.ndef_fc.read_access);
1339 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1340 " WriteAccess: 0x%02X", p_t4t->cc_file.ndef_fc.write_access);
nxpandroidc7611652015-09-23 16:42:05 +05301341
nxpandroid8f6d0532017-07-12 18:25:30 +05301342 if (rw_t4t_validate_cc_file()) {
1343 if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
1344 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1345 } else {
1346 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
nxpandroidc7611652015-09-23 16:42:05 +05301347 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301348 break;
1349 }
nxpandroidc7611652015-09-23 16:42:05 +05301350 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301351 }
nxpandroidc7611652015-09-23 16:42:05 +05301352
nxpandroid8f6d0532017-07-12 18:25:30 +05301353 /* invalid response or CC file */
1354 p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1355 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1356 break;
nxpandroidc7611652015-09-23 16:42:05 +05301357
1358 case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
1359
nxpandroid8f6d0532017-07-12 18:25:30 +05301360 /* NDEF file has been selected then read the first 2 bytes (NLEN) */
1361 if (!rw_t4t_read_file(0, T4T_FILE_LENGTH_SIZE, false)) {
1362 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1363 } else {
1364 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_NLEN;
1365 }
1366 break;
nxpandroidc7611652015-09-23 16:42:05 +05301367
1368 case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
1369
nxpandroid8f6d0532017-07-12 18:25:30 +05301370 /* NLEN has been read then report upper layer */
1371 if (p_r_apdu->len == T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE) {
1372 /* get length of NDEF */
1373 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1374 BE_STREAM_TO_UINT16(nlen, p);
nxpandroidc7611652015-09-23 16:42:05 +05301375
nxpandroid8f6d0532017-07-12 18:25:30 +05301376 if (nlen <=
1377 p_t4t->cc_file.ndef_fc.max_file_size - T4T_FILE_LENGTH_SIZE) {
1378 p_t4t->ndef_status = RW_T4T_NDEF_STATUS_NDEF_DETECTED;
nxpandroidc7611652015-09-23 16:42:05 +05301379
nxpandroid8f6d0532017-07-12 18:25:30 +05301380 if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) {
1381 p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
1382 }
nxpandroidc7611652015-09-23 16:42:05 +05301383
nxpandroid8f6d0532017-07-12 18:25:30 +05301384 /* Get max bytes to read per command */
1385 if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ) {
1386 p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
1387 } else {
1388 p_t4t->max_read_size = p_t4t->cc_file.max_le;
1389 }
nxpandroidc7611652015-09-23 16:42:05 +05301390
nxpandroid8f6d0532017-07-12 18:25:30 +05301391 /* Le: valid range is 0x01 to 0xFF */
1392 if (p_t4t->max_read_size >= T4T_MAX_LENGTH_LE) {
1393 p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
1394 }
nxpandroidc7611652015-09-23 16:42:05 +05301395
nxpandroid8f6d0532017-07-12 18:25:30 +05301396 /* Get max bytes to update per command */
1397 if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE) {
1398 p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
1399 } else {
1400 p_t4t->max_update_size = p_t4t->cc_file.max_lc;
1401 }
nxpandroidc7611652015-09-23 16:42:05 +05301402
nxpandroid8f6d0532017-07-12 18:25:30 +05301403 /* Lc: valid range is 0x01 to 0xFF */
1404 if (p_t4t->max_update_size >= T4T_MAX_LENGTH_LC) {
1405 p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
1406 }
nxpandroidc7611652015-09-23 16:42:05 +05301407
nxpandroid8f6d0532017-07-12 18:25:30 +05301408 p_t4t->ndef_length = nlen;
1409 p_t4t->state = RW_T4T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301410
nxpandroid8f6d0532017-07-12 18:25:30 +05301411 if (rw_cb.p_cback) {
1412 rw_data.ndef.status = NFC_STATUS_OK;
1413 rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
1414 rw_data.ndef.max_size =
1415 (uint32_t)(p_t4t->cc_file.ndef_fc.max_file_size -
1416 (uint16_t)T4T_FILE_LENGTH_SIZE);
1417 rw_data.ndef.cur_size = nlen;
1418 rw_data.ndef.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
1419 if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) {
1420 rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
nxpandroidc7611652015-09-23 16:42:05 +05301421 }
nxpandroidc7611652015-09-23 16:42:05 +05301422
nxpandroid8f6d0532017-07-12 18:25:30 +05301423 (*(rw_cb.p_cback))(RW_T4T_NDEF_DETECT_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301424
nxf24591c1cbeab2018-02-21 17:32:26 +05301425 DLOG_IF(INFO, nfc_debug_enabled)
1426 << StringPrintf("Sent RW_T4T_NDEF_DETECT_EVT");
nxpandroid8f6d0532017-07-12 18:25:30 +05301427 }
1428 } else {
1429 /* NLEN should be less than max file size */
nxf24591c1cbeab2018-02-21 17:32:26 +05301430 LOG(ERROR) << StringPrintf(
1431 "NLEN (%d) + 2 must be <= max file "
nxpandroid8f6d0532017-07-12 18:25:30 +05301432 "size (%d)",
1433 nlen, p_t4t->cc_file.ndef_fc.max_file_size);
1434
1435 p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1436 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
nxpandroidc7611652015-09-23 16:42:05 +05301437 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301438 } else {
1439 /* response payload size should be T4T_FILE_LENGTH_SIZE */
nxf24591c1cbeab2018-02-21 17:32:26 +05301440 LOG(ERROR) << StringPrintf(
1441 "Length (%d) of R-APDU must be %d", p_r_apdu->len,
1442 T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE);
nxpandroid8f6d0532017-07-12 18:25:30 +05301443
1444 p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
1445 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1446 }
1447 break;
nxpandroidc7611652015-09-23 16:42:05 +05301448
1449 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301450 LOG(ERROR) << StringPrintf("unknown sub_state=%d", p_t4t->sub_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301451 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1452 break;
1453 }
nxpandroidc7611652015-09-23 16:42:05 +05301454}
1455
1456/*******************************************************************************
1457**
1458** Function rw_t4t_sm_read_ndef
1459**
1460** Description State machine for NDEF read procedure
1461**
1462** Returns none
1463**
1464*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301465static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu) {
1466 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1467 uint8_t* p;
1468 uint16_t status_words;
1469 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301470
nxf24591c1cbeab2018-02-21 17:32:26 +05301471 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1472 "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1473 p_t4t->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301474
nxpandroid8f6d0532017-07-12 18:25:30 +05301475 /* get status words */
1476 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1477 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1478 BE_STREAM_TO_UINT16(status_words, p);
nxpandroidc7611652015-09-23 16:42:05 +05301479
nxpandroid8f6d0532017-07-12 18:25:30 +05301480 if (status_words != T4T_RSP_CMD_CMPLTED) {
1481 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1482 GKI_freebuf(p_r_apdu);
1483 return;
1484 }
nxpandroidc7611652015-09-23 16:42:05 +05301485
nxpandroid8f6d0532017-07-12 18:25:30 +05301486 switch (p_t4t->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301487 case RW_T4T_SUBSTATE_WAIT_READ_RESP:
1488
nxpandroid8f6d0532017-07-12 18:25:30 +05301489 /* Read partial or complete data */
1490 p_r_apdu->len -= T4T_RSP_STATUS_WORDS_SIZE;
nxpandroidc7611652015-09-23 16:42:05 +05301491
nxpandroid8f6d0532017-07-12 18:25:30 +05301492 if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length)) {
1493 p_t4t->rw_length -= p_r_apdu->len;
1494 p_t4t->rw_offset += p_r_apdu->len;
nxpandroidc7611652015-09-23 16:42:05 +05301495
nxpandroid8f6d0532017-07-12 18:25:30 +05301496 if (rw_cb.p_cback) {
1497 rw_data.data.status = NFC_STATUS_OK;
1498 rw_data.data.p_data = p_r_apdu;
nxpandroidc7611652015-09-23 16:42:05 +05301499
nxpandroid8f6d0532017-07-12 18:25:30 +05301500 /* if need to read more data */
1501 if (p_t4t->rw_length > 0) {
1502 (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_EVT, &rw_data);
nxpandroidc7611652015-09-23 16:42:05 +05301503
nxpandroid8f6d0532017-07-12 18:25:30 +05301504 if (!rw_t4t_read_file(p_t4t->rw_offset, p_t4t->rw_length, true)) {
1505 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
nxpandroidc7611652015-09-23 16:42:05 +05301506 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301507 } else {
1508 p_t4t->state = RW_T4T_STATE_IDLE;
1509
1510 (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_CPLT_EVT, &rw_data);
1511
nxf24591c1cbeab2018-02-21 17:32:26 +05301512 DLOG_IF(INFO, nfc_debug_enabled)
1513 << StringPrintf("Sent RW_T4T_NDEF_READ_CPLT_EVT");
nxpandroid8f6d0532017-07-12 18:25:30 +05301514 }
1515
1516 p_r_apdu = NULL;
1517 } else {
1518 p_t4t->rw_length = 0;
1519 p_t4t->state = RW_T4T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301520 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301521 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301522 LOG(ERROR) << StringPrintf(
1523 "invalid payload length (%d), rw_length "
nxpandroid8f6d0532017-07-12 18:25:30 +05301524 "(%d)",
1525 p_r_apdu->len, p_t4t->rw_length);
1526 rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
1527 }
1528 break;
nxpandroidc7611652015-09-23 16:42:05 +05301529
1530 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301531 LOG(ERROR) << StringPrintf("unknown sub_state = %d", p_t4t->sub_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301532 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1533 break;
1534 }
nxpandroidc7611652015-09-23 16:42:05 +05301535
nxpandroid8f6d0532017-07-12 18:25:30 +05301536 if (p_r_apdu) GKI_freebuf(p_r_apdu);
nxpandroidc7611652015-09-23 16:42:05 +05301537}
1538
1539/*******************************************************************************
1540**
1541** Function rw_t4t_sm_update_ndef
1542**
1543** Description State machine for NDEF update procedure
1544**
1545** Returns none
1546**
1547*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301548static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu) {
1549 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1550 uint8_t* p;
1551 uint16_t status_words;
1552 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301553
nxf24591c1cbeab2018-02-21 17:32:26 +05301554 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1555 "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1556 p_t4t->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301557
nxpandroid8f6d0532017-07-12 18:25:30 +05301558 /* Get status words */
1559 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1560 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1561 BE_STREAM_TO_UINT16(status_words, p);
nxpandroidc7611652015-09-23 16:42:05 +05301562
nxpandroid8f6d0532017-07-12 18:25:30 +05301563 if (status_words != T4T_RSP_CMD_CMPLTED) {
1564 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1565 return;
1566 }
nxpandroidc7611652015-09-23 16:42:05 +05301567
nxpandroid8f6d0532017-07-12 18:25:30 +05301568 switch (p_t4t->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301569 case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
1570
nxpandroid8f6d0532017-07-12 18:25:30 +05301571 /* NLEN has been updated */
1572 /* if need to update data */
1573 if (p_t4t->p_update_data) {
1574 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_RESP;
nxpandroidc7611652015-09-23 16:42:05 +05301575
nxpandroid8f6d0532017-07-12 18:25:30 +05301576 if (!rw_t4t_update_file()) {
1577 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1578 p_t4t->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05301579 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301580 } else {
1581 p_t4t->state = RW_T4T_STATE_IDLE;
nxpandroidc7611652015-09-23 16:42:05 +05301582
nxpandroid8f6d0532017-07-12 18:25:30 +05301583 /* just finished last step of updating (updating NLEN) */
1584 if (rw_cb.p_cback) {
1585 rw_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301586
nxpandroid8f6d0532017-07-12 18:25:30 +05301587 (*(rw_cb.p_cback))(RW_T4T_NDEF_UPDATE_CPLT_EVT, &rw_data);
nxf24591c1cbeab2018-02-21 17:32:26 +05301588 DLOG_IF(INFO, nfc_debug_enabled)
1589 << StringPrintf("Sent RW_T4T_NDEF_UPDATE_CPLT_EVT");
nxpandroidc7611652015-09-23 16:42:05 +05301590 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301591 }
1592 break;
nxpandroidc7611652015-09-23 16:42:05 +05301593
1594 case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
1595
nxpandroid8f6d0532017-07-12 18:25:30 +05301596 /* if updating is not completed */
1597 if (p_t4t->rw_length > 0) {
1598 if (!rw_t4t_update_file()) {
1599 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1600 p_t4t->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05301601 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301602 } else {
1603 p_t4t->p_update_data = NULL;
nxpandroidc7611652015-09-23 16:42:05 +05301604
nxpandroid8f6d0532017-07-12 18:25:30 +05301605 /* update NLEN as last step of updating file */
1606 if (!rw_t4t_update_nlen(p_t4t->ndef_length)) {
1607 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1608 } else {
1609 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
nxpandroidc7611652015-09-23 16:42:05 +05301610 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301611 }
1612 break;
nxpandroidc7611652015-09-23 16:42:05 +05301613
1614 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301615 LOG(ERROR) << StringPrintf("unknown sub_state = %d", p_t4t->sub_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301616 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1617 break;
1618 }
nxpandroidc7611652015-09-23 16:42:05 +05301619}
1620
1621/*******************************************************************************
1622**
1623** Function rw_t4t_sm_set_readonly
1624**
1625** Description State machine for CC update procedure
1626**
1627** Returns none
1628**
1629*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301630static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu) {
1631 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1632 uint8_t* p;
1633 uint16_t status_words;
1634 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301635
nxf24591c1cbeab2018-02-21 17:32:26 +05301636 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1637 "sub_state:%s (%d)", rw_t4t_get_sub_state_name(p_t4t->sub_state).c_str(),
1638 p_t4t->sub_state);
nxpandroidc7611652015-09-23 16:42:05 +05301639
nxpandroid8f6d0532017-07-12 18:25:30 +05301640 /* Get status words */
1641 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
1642 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
1643 BE_STREAM_TO_UINT16(status_words, p);
nxpandroidc7611652015-09-23 16:42:05 +05301644
nxpandroid8f6d0532017-07-12 18:25:30 +05301645 if (status_words != T4T_RSP_CMD_CMPLTED) {
1646 rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
1647 return;
1648 }
nxpandroidc7611652015-09-23 16:42:05 +05301649
nxpandroid8f6d0532017-07-12 18:25:30 +05301650 switch (p_t4t->sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05301651 case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
1652
nxpandroid8f6d0532017-07-12 18:25:30 +05301653 /* CC file has been selected then update write access to read-only in CC
1654 * file */
1655 if (!rw_t4t_update_cc_to_readonly()) {
1656 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1657 } else {
1658 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_CC;
1659 }
1660 break;
nxpandroidc7611652015-09-23 16:42:05 +05301661
1662 case RW_T4T_SUBSTATE_WAIT_UPDATE_CC:
nxpandroid8f6d0532017-07-12 18:25:30 +05301663 /* CC Updated, Select NDEF File to allow NDEF operation */
1664 p_t4t->cc_file.ndef_fc.write_access = T4T_FC_NO_WRITE_ACCESS;
1665 p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
nxpandroidc7611652015-09-23 16:42:05 +05301666
nxpandroid8f6d0532017-07-12 18:25:30 +05301667 if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
1668 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1669 } else {
1670 p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
1671 }
1672 break;
nxpandroidc7611652015-09-23 16:42:05 +05301673
1674 case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301675 p_t4t->state = RW_T4T_STATE_IDLE;
1676 /* just finished last step of configuring tag read only (Selecting NDEF
1677 * file CC) */
1678 if (rw_cb.p_cback) {
1679 rw_data.status = NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301680
nxf24591c1cbeab2018-02-21 17:32:26 +05301681 DLOG_IF(INFO, nfc_debug_enabled)
1682 << StringPrintf("Sent RW_T4T_SET_TO_RO_EVT");
nxpandroid8f6d0532017-07-12 18:25:30 +05301683 (*(rw_cb.p_cback))(RW_T4T_SET_TO_RO_EVT, &rw_data);
1684 }
1685 break;
nxpandroidc7611652015-09-23 16:42:05 +05301686
1687 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301688 LOG(ERROR) << StringPrintf("unknown sub_state = %d", p_t4t->sub_state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301689 rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
1690 break;
1691 }
nxpandroidc7611652015-09-23 16:42:05 +05301692}
1693
1694/*******************************************************************************
1695**
1696** Function rw_t4t_process_timeout
1697**
1698** Description process timeout event
1699**
1700** Returns none
1701**
1702*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301703void rw_t4t_process_timeout(TIMER_LIST_ENT* p_tle) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301704 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event=%d", p_tle->event);
nxpandroidc7611652015-09-23 16:42:05 +05301705
nxpandroid8f6d0532017-07-12 18:25:30 +05301706 if (p_tle->event == NFC_TTYPE_RW_T4T_RESPONSE) {
1707 rw_t4t_handle_error(NFC_STATUS_TIMEOUT, 0, 0);
1708 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301709 LOG(ERROR) << StringPrintf("unknown event=%d", p_tle->event);
nxpandroid8f6d0532017-07-12 18:25:30 +05301710 }
1711}
1712
1713/*******************************************************************************
1714**
1715** Function rw_t4t_handle_isodep_nak_rsp
1716**
1717** Description This function handles the response and ntf .
1718**
1719** Returns none
1720**
1721*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301722void rw_t4t_handle_isodep_nak_rsp(uint8_t status, bool is_ntf) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301723 tRW_DATA rw_data;
1724 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
nxf24591c1cbeab2018-02-21 17:32:26 +05301725 DLOG_IF(INFO, nfc_debug_enabled)
1726 << StringPrintf("rw_t4t_handle_isodep_nak_rsp %d", status);
nxpandroid8f6d0532017-07-12 18:25:30 +05301727 if (is_ntf || (status != NFC_STATUS_OK)) {
1728 rw_data.status = status;
1729 nfc_stop_quick_timer(&p_t4t->timer);
1730 p_t4t->state = RW_T4T_STATE_IDLE;
1731 (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
1732 }
nxpandroidc7611652015-09-23 16:42:05 +05301733}
1734
1735/*******************************************************************************
1736**
1737** Function rw_t4t_data_cback
1738**
1739** Description This callback function receives the data from NFCC.
1740**
1741** Returns none
1742**
1743*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05301744static void rw_t4t_data_cback(__attribute__((unused)) uint8_t conn_id,
1745 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301746 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
1747 NFC_HDR* p_r_apdu;
1748 tRW_DATA rw_data;
nxpandroidc7611652015-09-23 16:42:05 +05301749
nxpandroid8f6d0532017-07-12 18:25:30 +05301750 uint8_t begin_state = p_t4t->state;
nxpandroidc7611652015-09-23 16:42:05 +05301751
nxf24591c1cbeab2018-02-21 17:32:26 +05301752 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
nxpandroid8f6d0532017-07-12 18:25:30 +05301753 nfc_stop_quick_timer(&p_t4t->timer);
nxpandroidc7611652015-09-23 16:42:05 +05301754
nxpandroid8f6d0532017-07-12 18:25:30 +05301755 switch (event) {
nxpandroidc7611652015-09-23 16:42:05 +05301756 case NFC_DEACTIVATE_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +05301757 NFC_SetStaticRfCback(NULL);
1758 p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED;
1759 return;
nxpandroidc7611652015-09-23 16:42:05 +05301760
1761 case NFC_ERROR_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +05301762 if (p_t4t->state == RW_T4T_STATE_PRESENCE_CHECK) {
1763 p_t4t->state = RW_T4T_STATE_IDLE;
1764 rw_data.status = NFC_STATUS_FAILED;
1765 (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
1766 } else if (p_t4t->state == RW_T4T_STATE_NDEF_FORMAT) {
1767 p_t4t->state = RW_T4T_STATE_IDLE;
1768 rw_data.status = NFC_STATUS_FAILED;
1769 (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
1770 } else if (p_t4t->state != RW_T4T_STATE_IDLE) {
nxpandroid8f6d0532017-07-12 18:25:30 +05301771 rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
nxpandroid8f6d0532017-07-12 18:25:30 +05301772 rw_t4t_handle_error(rw_data.status, 0, 0);
1773 } else {
1774 p_t4t->state = RW_T4T_STATE_IDLE;
1775 rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
1776 (*(rw_cb.p_cback))(RW_T4T_INTF_ERROR_EVT, &rw_data);
1777 }
1778 return;
nxpandroidc7611652015-09-23 16:42:05 +05301779
1780 case NFC_DATA_CEVT:
nxpandroid8f6d0532017-07-12 18:25:30 +05301781 p_r_apdu = (NFC_HDR*)p_data->data.p_data;
1782 break;
nxpandroidc7611652015-09-23 16:42:05 +05301783
nxpandroidc7611652015-09-23 16:42:05 +05301784 default:
nxpandroid8f6d0532017-07-12 18:25:30 +05301785 return;
1786 }
nxpandroidc7611652015-09-23 16:42:05 +05301787
nxf24591c1cbeab2018-02-21 17:32:26 +05301788 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1789 "RW T4T state: <%s (%d)>", rw_t4t_get_state_name(p_t4t->state).c_str(),
1790 p_t4t->state);
nxpandroidc7611652015-09-23 16:42:05 +05301791
nxpandroid8f6d0532017-07-12 18:25:30 +05301792 switch (p_t4t->state) {
nxpandroidc7611652015-09-23 16:42:05 +05301793 case RW_T4T_STATE_IDLE:
nxpandroid8f6d0532017-07-12 18:25:30 +05301794/* Unexpected R-APDU, it should be raw frame response */
1795/* forward to upper layer without parsing */
nxf24591c1cbeab2018-02-21 17:32:26 +05301796DLOG_IF(INFO, nfc_debug_enabled)
1797 << StringPrintf("RW T4T Raw Frame: Len [0x%X] Status [%s]", p_r_apdu->len,
1798 NFC_GetStatusName(p_data->data.status).c_str());
1799if (rw_cb.p_cback) {
1800 rw_data.raw_frame.status = p_data->data.status;
1801 rw_data.raw_frame.p_data = p_r_apdu;
1802 (*(rw_cb.p_cback))(RW_T4T_RAW_FRAME_EVT, &rw_data);
1803 p_r_apdu = NULL;
nxpandroid8f6d0532017-07-12 18:25:30 +05301804 } else {
1805 GKI_freebuf(p_r_apdu);
1806 }
1807 break;
nxpandroidc7611652015-09-23 16:42:05 +05301808 case RW_T4T_STATE_DETECT_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05301809 rw_t4t_sm_detect_ndef(p_r_apdu);
1810 GKI_freebuf(p_r_apdu);
1811 break;
nxpandroidc7611652015-09-23 16:42:05 +05301812 case RW_T4T_STATE_READ_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05301813 rw_t4t_sm_read_ndef(p_r_apdu);
1814 /* p_r_apdu may send upper lyaer */
1815 break;
nxpandroidc7611652015-09-23 16:42:05 +05301816 case RW_T4T_STATE_UPDATE_NDEF:
nxpandroid8f6d0532017-07-12 18:25:30 +05301817 rw_t4t_sm_update_ndef(p_r_apdu);
1818 GKI_freebuf(p_r_apdu);
1819 break;
nxpandroidc7611652015-09-23 16:42:05 +05301820 case RW_T4T_STATE_PRESENCE_CHECK:
nxpandroid8f6d0532017-07-12 18:25:30 +05301821 /* if any response, send presence check with ok */
1822 rw_data.status = NFC_STATUS_OK;
1823 p_t4t->state = RW_T4T_STATE_IDLE;
1824 (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
1825 GKI_freebuf(p_r_apdu);
1826 break;
nxpandroidc7611652015-09-23 16:42:05 +05301827 case RW_T4T_STATE_SET_READ_ONLY:
nxpandroid8f6d0532017-07-12 18:25:30 +05301828 rw_t4t_sm_set_readonly(p_r_apdu);
1829 GKI_freebuf(p_r_apdu);
1830 break;
nxpandroidc7611652015-09-23 16:42:05 +05301831 case RW_T4T_STATE_NDEF_FORMAT:
nxpandroid8f6d0532017-07-12 18:25:30 +05301832 rw_t4t_sm_ndef_format(p_r_apdu);
1833 GKI_freebuf(p_r_apdu);
1834 break;
nxpandroidc7611652015-09-23 16:42:05 +05301835 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05301836 LOG(ERROR) << StringPrintf("invalid state=%d", p_t4t->state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301837 GKI_freebuf(p_r_apdu);
1838 break;
1839 }
nxpandroidc7611652015-09-23 16:42:05 +05301840
nxpandroid8f6d0532017-07-12 18:25:30 +05301841 if (begin_state != p_t4t->state) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301842 DLOG_IF(INFO, nfc_debug_enabled)
1843 << StringPrintf("RW T4T state changed:<%s> -> <%s>",
1844 rw_t4t_get_state_name(begin_state).c_str(),
1845 rw_t4t_get_state_name(p_t4t->state).c_str());
nxpandroid8f6d0532017-07-12 18:25:30 +05301846 }
nxpandroidc7611652015-09-23 16:42:05 +05301847}
1848
nxpandroidc7611652015-09-23 16:42:05 +05301849/*******************************************************************************
1850**
1851** Function RW_T4tFormatNDef
1852**
1853** Description format T4T tag
1854**
1855** Returns NFC_STATUS_OK if success
1856**
1857*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301858tNFC_STATUS RW_T4tFormatNDef(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301859 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301860
nxpandroid8f6d0532017-07-12 18:25:30 +05301861 if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301862 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
1863 rw_cb.tcb.t4t.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301864 return NFC_STATUS_FAILED;
1865 }
nxpandroidc7611652015-09-23 16:42:05 +05301866
nxpandroid8f6d0532017-07-12 18:25:30 +05301867 rw_cb.tcb.t4t.card_type = 0x00;
nxf24591c1cbeab2018-02-21 17:32:26 +05301868
nxpandroid8f6d0532017-07-12 18:25:30 +05301869 if (!rw_t4t_get_hw_version()) {
1870 return NFC_STATUS_FAILED;
1871 }
nxf24591c1cbeab2018-02-21 17:32:26 +05301872
nxpandroid8f6d0532017-07-12 18:25:30 +05301873 rw_cb.tcb.t4t.state = RW_T4T_STATE_NDEF_FORMAT;
1874 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION;
nxpandroidc7611652015-09-23 16:42:05 +05301875
nxpandroid8f6d0532017-07-12 18:25:30 +05301876 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301877}
nxpandroidcdd30442016-05-27 17:26:18 +05301878
nxpandroidc7611652015-09-23 16:42:05 +05301879/*******************************************************************************
1880**
1881** Function rw_t4t_select
1882**
1883** Description Initialise T4T
1884**
1885** Returns NFC_STATUS_OK if success
1886**
1887*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301888tNFC_STATUS rw_t4t_select(void) {
1889 tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
nxpandroidc7611652015-09-23 16:42:05 +05301890
nxf24591c1cbeab2018-02-21 17:32:26 +05301891 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301892
nxpandroid8f6d0532017-07-12 18:25:30 +05301893 NFC_SetStaticRfCback(rw_t4t_data_cback);
nxpandroidc7611652015-09-23 16:42:05 +05301894
nxpandroid8f6d0532017-07-12 18:25:30 +05301895 p_t4t->state = RW_T4T_STATE_IDLE;
1896 p_t4t->version = T4T_MY_VERSION;
nxpandroidc7611652015-09-23 16:42:05 +05301897
nxpandroid8f6d0532017-07-12 18:25:30 +05301898 /* set it min of max R-APDU data size before reading CC file */
1899 p_t4t->cc_file.max_le = T4T_MIN_MLE;
nxpandroidc7611652015-09-23 16:42:05 +05301900
nxpandroid8f6d0532017-07-12 18:25:30 +05301901 /* These will be udated during NDEF detection */
1902 p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
1903 p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
nxpandroidc7611652015-09-23 16:42:05 +05301904
nxpandroid8f6d0532017-07-12 18:25:30 +05301905 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301906}
1907
1908/*******************************************************************************
1909**
1910** Function RW_T4tDetectNDef
1911**
1912** Description This function performs NDEF detection procedure
1913**
1914** RW_T4T_NDEF_DETECT_EVT will be returned
1915**
1916** Returns NFC_STATUS_OK if success
1917** NFC_STATUS_FAILED if T4T is busy or other error
1918**
1919*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301920tNFC_STATUS RW_T4tDetectNDef(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301921 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301922
nxpandroid8f6d0532017-07-12 18:25:30 +05301923 if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301924 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
1925 rw_cb.tcb.t4t.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301926 return NFC_STATUS_FAILED;
1927 }
1928
1929 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
1930 /* NDEF Tag application has been selected then select CC file */
1931 if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
1932 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301933 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301934 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
1935 } else {
1936 /* Select NDEF Tag Application */
1937 if (!rw_t4t_select_application(rw_cb.tcb.t4t.version)) {
1938 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301939 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301940 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
1941 }
nxpandroidc7611652015-09-23 16:42:05 +05301942
nxpandroid8f6d0532017-07-12 18:25:30 +05301943 rw_cb.tcb.t4t.state = RW_T4T_STATE_DETECT_NDEF;
nxpandroidc7611652015-09-23 16:42:05 +05301944
nxpandroid8f6d0532017-07-12 18:25:30 +05301945 return NFC_STATUS_OK;
nxpandroidc7611652015-09-23 16:42:05 +05301946}
1947
1948/*******************************************************************************
1949**
1950** Function RW_T4tReadNDef
1951**
1952** Description This function performs NDEF read procedure
1953** Note: RW_T4tDetectNDef () must be called before using this
1954**
1955** The following event will be returned
1956** RW_T4T_NDEF_READ_EVT for each segmented NDEF message
nxpandroid8f6d0532017-07-12 18:25:30 +05301957** RW_T4T_NDEF_READ_CPLT_EVT for the last segment or
1958** complete NDEF
nxpandroidc7611652015-09-23 16:42:05 +05301959** RW_T4T_NDEF_READ_FAIL_EVT for failure
1960**
1961** Returns NFC_STATUS_OK if success
1962** NFC_STATUS_FAILED if T4T is busy or other error
1963**
1964*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301965tNFC_STATUS RW_T4tReadNDef(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301966 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05301967
nxpandroid8f6d0532017-07-12 18:25:30 +05301968 if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301969 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
1970 rw_cb.tcb.t4t.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05301971 return NFC_STATUS_FAILED;
1972 }
1973
1974 /* if NDEF has been detected */
1975 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
1976 /* start reading NDEF */
1977 if (!rw_t4t_read_file(T4T_FILE_LENGTH_SIZE, rw_cb.tcb.t4t.ndef_length,
1978 false)) {
1979 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05301980 }
1981
nxpandroid8f6d0532017-07-12 18:25:30 +05301982 rw_cb.tcb.t4t.state = RW_T4T_STATE_READ_NDEF;
1983 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
nxpandroidc7611652015-09-23 16:42:05 +05301984
nxpandroid8f6d0532017-07-12 18:25:30 +05301985 return NFC_STATUS_OK;
1986 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05301987 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05301988 return NFC_STATUS_FAILED;
1989 }
nxpandroidc7611652015-09-23 16:42:05 +05301990}
1991
1992/*******************************************************************************
1993**
1994** Function RW_T4tUpdateNDef
1995**
1996** Description This function performs NDEF update procedure
1997** Note: RW_T4tDetectNDef () must be called before using this
nxpandroid8f6d0532017-07-12 18:25:30 +05301998** Updating data must not be removed until returning
1999** event
nxpandroidc7611652015-09-23 16:42:05 +05302000**
2001** The following event will be returned
2002** RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
2003** RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
2004**
2005** Returns NFC_STATUS_OK if success
2006** NFC_STATUS_FAILED if T4T is busy or other error
2007**
2008*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302009tNFC_STATUS RW_T4tUpdateNDef(uint16_t length, uint8_t* p_data) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302010 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("length:%d", length);
nxpandroidc7611652015-09-23 16:42:05 +05302011
nxpandroid8f6d0532017-07-12 18:25:30 +05302012 if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302013 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
2014 rw_cb.tcb.t4t.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302015 return NFC_STATUS_FAILED;
2016 }
2017
2018 /* if NDEF has been detected */
2019 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
2020 /* if read-only */
2021 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302022 LOG(ERROR) << StringPrintf("NDEF is read-only");
nxpandroid8f6d0532017-07-12 18:25:30 +05302023 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302024 }
2025
nxpandroid8f6d0532017-07-12 18:25:30 +05302026 if (rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size <
2027 length + T4T_FILE_LENGTH_SIZE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302028 LOG(ERROR) << StringPrintf(
2029 "data (%d bytes) plus NLEN is more than max file "
nxpandroid8f6d0532017-07-12 18:25:30 +05302030 "size (%d)",
2031 length, rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size);
2032 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302033 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302034
2035 /* store NDEF length and data */
2036 rw_cb.tcb.t4t.ndef_length = length;
2037 rw_cb.tcb.t4t.p_update_data = p_data;
2038
2039 rw_cb.tcb.t4t.rw_offset = T4T_FILE_LENGTH_SIZE;
2040 rw_cb.tcb.t4t.rw_length = length;
2041
2042 /* set NLEN to 0x0000 for the first step */
2043 if (!rw_t4t_update_nlen(0x0000)) {
2044 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302045 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302046
2047 rw_cb.tcb.t4t.state = RW_T4T_STATE_UPDATE_NDEF;
2048 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
2049
2050 return NFC_STATUS_OK;
2051 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302052 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05302053 return NFC_STATUS_FAILED;
2054 }
nxpandroidc7611652015-09-23 16:42:05 +05302055}
2056
2057/*****************************************************************************
2058**
2059** Function RW_T4tPresenceCheck
2060**
2061** Description
2062** Check if the tag is still in the field.
2063**
2064** The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2065** or non-presence.
nxpandroid8f6d0532017-07-12 18:25:30 +05302066**
2067** option is RW_T4T_CHK_EMPTY_I_BLOCK, use empty I block for presence check
nxpandroidc7611652015-09-23 16:42:05 +05302068**
2069** Returns
2070** NFC_STATUS_OK, if raw data frame sent
2071** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2072** NFC_STATUS_FAILED: other error
2073**
2074*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302075tNFC_STATUS RW_T4tPresenceCheck(uint8_t option) {
2076 tNFC_STATUS retval = NFC_STATUS_OK;
2077 tRW_DATA evt_data;
2078 bool status;
2079 NFC_HDR* p_data;
nxpandroidc7611652015-09-23 16:42:05 +05302080
nxf24591c1cbeab2018-02-21 17:32:26 +05302081 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%d", option);
nxpandroidc7611652015-09-23 16:42:05 +05302082
nxpandroid8f6d0532017-07-12 18:25:30 +05302083 /* If RW_SelectTagType was not called (no conn_callback) return failure */
2084 if (!rw_cb.p_cback) {
2085 retval = NFC_STATUS_FAILED;
2086 }
2087 /* If we are not activated, then RW_T4T_PRESENCE_CHECK_EVT with
2088 NFC_STATUS_FAILED */
2089 else if (rw_cb.tcb.t4t.state == RW_T4T_STATE_NOT_ACTIVATED) {
2090 evt_data.status = NFC_STATUS_FAILED;
2091 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
2092 }
2093 /* If command is pending, assume tag is still present */
2094 else if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
2095 evt_data.status = NFC_STATUS_OK;
2096 (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
2097 } else {
2098 status = false;
2099 if (option == RW_T4T_CHK_EMPTY_I_BLOCK) {
2100 /* use empty I block for presence check */
2101 p_data = (NFC_HDR*)GKI_getbuf(NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE);
2102 if (p_data != NULL) {
2103 p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
2104 p_data->len = 0;
2105 if (NFC_SendData(NFC_RF_CONN_ID, (NFC_HDR*)p_data) == NFC_STATUS_OK)
2106 status = true;
2107 }
2108 } else if (option == RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302109 if (NFC_ISODEPNakPresCheck() == NFC_STATUS_OK) status = true;
nxpandroidc7611652015-09-23 16:42:05 +05302110 }
2111
nxpandroid8f6d0532017-07-12 18:25:30 +05302112 if (status == true) {
2113 rw_cb.tcb.t4t.state = RW_T4T_STATE_PRESENCE_CHECK;
2114 } else {
2115 retval = NFC_STATUS_NO_BUFFERS;
2116 }
2117 }
2118
2119 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302120}
2121
2122/*****************************************************************************
2123**
2124** Function RW_T4tSetNDefReadOnly
2125**
2126** Description This function performs NDEF read-only procedure
2127** Note: RW_T4tDetectNDef() must be called before using this
2128**
2129** The RW_T4T_SET_TO_RO_EVT event will be returned.
2130**
2131** Returns NFC_STATUS_OK if success
2132** NFC_STATUS_FAILED if T4T is busy or other error
2133**
2134*****************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05302135tNFC_STATUS RW_T4tSetNDefReadOnly(void) {
2136 tNFC_STATUS retval = NFC_STATUS_OK;
2137 tRW_DATA evt_data;
nxpandroidc7611652015-09-23 16:42:05 +05302138
nxf24591c1cbeab2018-02-21 17:32:26 +05302139 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
nxpandroidc7611652015-09-23 16:42:05 +05302140
nxpandroid8f6d0532017-07-12 18:25:30 +05302141 if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302142 LOG(ERROR) << StringPrintf("Unable to start command at state (0x%X)",
2143 rw_cb.tcb.t4t.state);
nxpandroid8f6d0532017-07-12 18:25:30 +05302144 return NFC_STATUS_FAILED;
2145 }
2146
2147 /* if NDEF has been detected */
2148 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
2149 /* if read-only */
2150 if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
nxf24591c1cbeab2018-02-21 17:32:26 +05302151 DLOG_IF(INFO, nfc_debug_enabled)
2152 << StringPrintf("NDEF is already read-only");
nxpandroid8f6d0532017-07-12 18:25:30 +05302153
2154 evt_data.status = NFC_STATUS_OK;
2155 (*rw_cb.p_cback)(RW_T4T_SET_TO_RO_EVT, &evt_data);
2156 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302157 }
2158
nxpandroid8f6d0532017-07-12 18:25:30 +05302159 /* NDEF Tag application has been selected then select CC file */
2160 if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
2161 return NFC_STATUS_FAILED;
nxpandroidc7611652015-09-23 16:42:05 +05302162 }
nxpandroid8f6d0532017-07-12 18:25:30 +05302163
2164 rw_cb.tcb.t4t.state = RW_T4T_STATE_SET_READ_ONLY;
2165 rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
2166
2167 return NFC_STATUS_OK;
2168 } else {
nxf24591c1cbeab2018-02-21 17:32:26 +05302169 LOG(ERROR) << StringPrintf("No NDEF detected");
nxpandroid8f6d0532017-07-12 18:25:30 +05302170 return NFC_STATUS_FAILED;
2171 }
2172 return (retval);
nxpandroidc7611652015-09-23 16:42:05 +05302173}
2174
nxpandroidc7611652015-09-23 16:42:05 +05302175/*******************************************************************************
2176**
2177** Function rw_t4t_get_state_name
2178**
2179** Description This function returns the state name.
2180**
2181** NOTE conditionally compiled to save memory.
2182**
2183** Returns pointer to the name
2184**
2185*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302186static std::string rw_t4t_get_state_name(uint8_t state) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302187 switch (state) {
nxpandroidc7611652015-09-23 16:42:05 +05302188 case RW_T4T_STATE_NOT_ACTIVATED:
nxf24591c1cbeab2018-02-21 17:32:26 +05302189 return "NOT_ACTIVATED";
nxpandroidc7611652015-09-23 16:42:05 +05302190 case RW_T4T_STATE_IDLE:
nxf24591c1cbeab2018-02-21 17:32:26 +05302191 return "IDLE";
nxpandroidc7611652015-09-23 16:42:05 +05302192 case RW_T4T_STATE_DETECT_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302193 return "NDEF_DETECTION";
nxpandroidc7611652015-09-23 16:42:05 +05302194 case RW_T4T_STATE_READ_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302195 return "READ_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302196 case RW_T4T_STATE_UPDATE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302197 return "UPDATE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302198 case RW_T4T_STATE_PRESENCE_CHECK:
nxf24591c1cbeab2018-02-21 17:32:26 +05302199 return "PRESENCE_CHECK";
nxpandroidc7611652015-09-23 16:42:05 +05302200 case RW_T4T_STATE_SET_READ_ONLY:
nxf24591c1cbeab2018-02-21 17:32:26 +05302201 return "SET_READ_ONLY";
nxpandroidc7611652015-09-23 16:42:05 +05302202 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05302203 return "???? UNKNOWN STATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05302204 }
nxpandroidc7611652015-09-23 16:42:05 +05302205}
2206
2207/*******************************************************************************
2208**
2209** Function rw_t4t_get_sub_state_name
2210**
2211** Description This function returns the sub_state name.
2212**
2213** NOTE conditionally compiled to save memory.
2214**
2215** Returns pointer to the name
2216**
2217*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +05302218static std::string rw_t4t_get_sub_state_name(uint8_t sub_state) {
nxpandroid8f6d0532017-07-12 18:25:30 +05302219 switch (sub_state) {
nxpandroidc7611652015-09-23 16:42:05 +05302220 case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
nxf24591c1cbeab2018-02-21 17:32:26 +05302221 return "WAIT_SELECT_APP";
nxpandroidc7611652015-09-23 16:42:05 +05302222 case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05302223 return "WAIT_SELECT_CC";
nxpandroidc7611652015-09-23 16:42:05 +05302224 case RW_T4T_SUBSTATE_WAIT_CC_FILE:
nxf24591c1cbeab2018-02-21 17:32:26 +05302225 return "WAIT_CC_FILE";
nxpandroidc7611652015-09-23 16:42:05 +05302226 case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
nxf24591c1cbeab2018-02-21 17:32:26 +05302227 return "WAIT_SELECT_NDEF_FILE";
nxpandroidc7611652015-09-23 16:42:05 +05302228 case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
nxf24591c1cbeab2018-02-21 17:32:26 +05302229 return "WAIT_READ_NLEN";
nxpandroidc7611652015-09-23 16:42:05 +05302230 case RW_T4T_SUBSTATE_WAIT_READ_RESP:
nxf24591c1cbeab2018-02-21 17:32:26 +05302231 return "WAIT_READ_RESP";
nxpandroidc7611652015-09-23 16:42:05 +05302232 case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
nxf24591c1cbeab2018-02-21 17:32:26 +05302233 return "WAIT_UPDATE_RESP";
nxpandroidc7611652015-09-23 16:42:05 +05302234 case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
nxf24591c1cbeab2018-02-21 17:32:26 +05302235 return "WAIT_UPDATE_NLEN";
nxpandroidc7611652015-09-23 16:42:05 +05302236 case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
nxf24591c1cbeab2018-02-21 17:32:26 +05302237 return "WAIT_GET_HW_VERSION";
nxpandroid8f6d0532017-07-12 18:25:30 +05302238 case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
nxf24591c1cbeab2018-02-21 17:32:26 +05302239 return "WAIT_GET_SW_VERSION";
nxpandroidc7611652015-09-23 16:42:05 +05302240 case RW_T4T_SUBSTATE_WAIT_GET_UID:
nxf24591c1cbeab2018-02-21 17:32:26 +05302241 return "WAIT_GET_UID";
nxpandroidc7611652015-09-23 16:42:05 +05302242 case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
nxf24591c1cbeab2018-02-21 17:32:26 +05302243 return "WAIT_CREATE_APP";
nxpandroidc7611652015-09-23 16:42:05 +05302244 case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05302245 return "WAIT_CREATE_CC";
nxpandroidc7611652015-09-23 16:42:05 +05302246 case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302247 return "WAIT_CREATE_NDEF";
nxpandroid8f6d0532017-07-12 18:25:30 +05302248 case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
nxf24591c1cbeab2018-02-21 17:32:26 +05302249 return "WAIT_WRITE_CC";
nxpandroidc7611652015-09-23 16:42:05 +05302250 case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
nxf24591c1cbeab2018-02-21 17:32:26 +05302251 return "WAIT_WRITE_NDEF";
nxpandroidc7611652015-09-23 16:42:05 +05302252 default:
nxf24591c1cbeab2018-02-21 17:32:26 +05302253 return "???? UNKNOWN SUBSTATE";
nxpandroid8f6d0532017-07-12 18:25:30 +05302254 }
nxpandroidc7611652015-09-23 16:42:05 +05302255}