1 /******************************************************************************
2 *
3 * Copyright (C) 2024 The Android Open Source Project.
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 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include <string.h>
22
23 #include <iomanip>
24 #include <unordered_map>
25
26 #include "ndef_utils.h"
27 #include "nfa_dm_int.h"
28 #include "nfa_mem_co.h"
29 #include "nfa_nfcee_int.h"
30
31 using android::base::StringPrintf;
32
33 void nfa_t4tnfcee_handle_t4t_evt(tRW_EVENT event, tRW_DATA* p_data);
34 void nfa_t4tnfcee_store_cc_info(NFC_HDR* p_data);
35 void nfa_t4tnfcee_notify_rx_evt(void);
36 void nfa_t4tnfcee_handle_file_operations(tRW_DATA* p_rwData);
37 bool isReadPermitted(void);
38 bool isWritePermitted(void);
39 bool isDataLenBelowMaxFileCapacity(void);
40 void nfa_t4tnfcee_store_rx_buf(NFC_HDR* p_data);
41 void nfa_t4tnfcee_initialize_data(tNFA_T4TNFCEE_MSG* p_data);
42 bool is_read_precondition_valid(tNFA_T4TNFCEE_MSG* p_data);
43 bool is_write_precondition_valid(tNFA_T4TNFCEE_MSG* p_data);
44 uint16_t nfa_t4tnfcee_get_len(tRW_DATA* p_rwData);
45 tNFC_STATUS getWritePreconditionStatus();
46 bool isError(tNFC_STATUS status);
47 unordered_map<uint16_t, tNFA_T4TNFCEE_FILE_INFO> ccFileInfo;
48
49 /*******************************************************************************
50 **
51 ** Function nfa_t4tnfcee_free_rx_buf
52 **
53 ** Description Free buffer allocated to hold incoming T4T message
54 **
55 ** Returns Nothing
56 **
57 *******************************************************************************/
nfa_t4tnfcee_free_rx_buf(void)58 void nfa_t4tnfcee_free_rx_buf(void) {
59 /*Free only if it is Read operation
60 For write, buffer will be passed from JNI which will be freed by JNI*/
61 if (((nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ) ||
62 (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_CLEAR) ||
63 (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ_CC_FILE)) &&
64 nfa_t4tnfcee_cb.p_dataBuf) {
65 nfa_mem_co_free(nfa_t4tnfcee_cb.p_dataBuf);
66 nfa_t4tnfcee_cb.p_dataBuf = NULL;
67 }
68 nfa_t4tnfcee_cb.rd_offset = 0x00;
69 nfa_t4tnfcee_cb.dataLen = 0x00;
70 }
71
72 /*******************************************************************************
73 **
74 ** Function nfa_t4tnfcee_exec_file_operation
75 **
76 ** Description Handles read sequence for Ndef and proprietary
77 **
78 ** Returns tNFA_STATUS
79 **
80 *******************************************************************************/
nfa_t4tnfcee_exec_file_operation()81 tNFA_STATUS nfa_t4tnfcee_exec_file_operation() {
82 tNFA_STATUS status = NFA_STATUS_FAILED;
83 LOG(DEBUG) << StringPrintf("%s", __func__);
84 status = RW_SetT4tNfceeInfo((tRW_CBACK*)nfa_t4tnfcee_handle_t4t_evt,
85 nfa_t4tnfcee_cb.connId);
86 if (status != NFA_STATUS_OK) {
87 LOG(DEBUG) << StringPrintf("%s: T4T info not able to set. Return",
88 __func__);
89 return status;
90 }
91 status = RW_T4tNfceeSelectApplication();
92 if (status != NFA_STATUS_OK) {
93 LOG(DEBUG) << StringPrintf("%s: T4T Select application failed", __func__);
94 return status;
95 } else {
96 nfa_t4tnfcee_cb.rw_state = WAIT_SELECT_APPLICATION;
97 return NFA_STATUS_OK;
98 }
99 }
100
101 /*******************************************************************************
102 **
103 ** Function nfa_t4tnfcee_handle_op_req
104 **
105 ** Description Handler for NFA_T4TNFCEE_OP_REQUEST_EVT, operation request
106 **
107 ** Returns true if caller should free p_data
108 ** false if caller does not need to free p_data
109 **
110 *******************************************************************************/
nfa_t4tnfcee_handle_op_req(tNFA_T4TNFCEE_MSG * p_data)111 bool nfa_t4tnfcee_handle_op_req(tNFA_T4TNFCEE_MSG* p_data) {
112 nfa_t4tnfcee_cb.cur_op = p_data->op_req.op;
113
114 /* Call appropriate handler for requested operation */
115 switch (p_data->op_req.op) {
116 case NFA_T4TNFCEE_OP_OPEN_CONNECTION: {
117 LOG(DEBUG) << StringPrintf("%s: NFA_T4TNFCEE_OP_OPEN_CONNECTION",
118 __func__);
119 nfa_t4tnfcee_proc_disc_evt(NFA_T4TNFCEE_OP_OPEN_CONNECTION);
120 } break;
121 case NFA_T4TNFCEE_OP_READ:
122 case NFA_T4TNFCEE_OP_READ_CC_FILE: {
123 LOG(DEBUG) << StringPrintf(
124 "%s: NFA_T4TNFCEE_OP_READ_CC_FILE/NFA_T4TNFCEE_OP_READ", __func__);
125 if (!is_read_precondition_valid(p_data)) {
126 LOG(DEBUG) << StringPrintf("%s: Failed", __func__);
127 nfa_t4tnfcee_cb.status = NFA_STATUS_INVALID_PARAM;
128 nfa_t4tnfcee_notify_rx_evt();
129 break;
130 }
131 nfa_t4tnfcee_initialize_data(p_data);
132 tNFA_STATUS status = nfa_t4tnfcee_exec_file_operation();
133 if (status != NFA_STATUS_OK) {
134 nfa_t4tnfcee_cb.status = NFA_STATUS_FAILED;
135 nfa_t4tnfcee_notify_rx_evt();
136 }
137 } break;
138 case NFA_T4TNFCEE_OP_WRITE: {
139 LOG(DEBUG) << StringPrintf("%s: NFA_T4TNFCEE_OP_WRITE", __func__);
140 if (!is_write_precondition_valid(p_data)) {
141 LOG(DEBUG) << StringPrintf("%s: Failed", __func__);
142 nfa_t4tnfcee_cb.status = NFA_STATUS_INVALID_PARAM;
143 nfa_t4tnfcee_notify_rx_evt();
144 break;
145 }
146 nfa_t4tnfcee_initialize_data(p_data);
147 if ((p_data->op_req.write.p_data != nullptr) &&
148 (p_data->op_req.write.len > 0)) {
149 nfa_t4tnfcee_cb.p_dataBuf = p_data->op_req.write.p_data;
150 nfa_t4tnfcee_cb.dataLen = p_data->op_req.write.len;
151 }
152 tNFA_STATUS status = nfa_t4tnfcee_exec_file_operation();
153 if (status != NFA_STATUS_OK) {
154 nfa_t4tnfcee_cb.status = NFA_STATUS_FAILED;
155 nfa_t4tnfcee_notify_rx_evt();
156 }
157 } break;
158 case NFA_T4TNFCEE_OP_CLEAR: {
159 LOG(DEBUG) << StringPrintf("%s: NFA_T4TNFCEE_OP_CLEAR", __func__);
160 nfa_t4tnfcee_initialize_data(p_data);
161 tNFA_STATUS status = nfa_t4tnfcee_exec_file_operation();
162 if (status != NFA_STATUS_OK) {
163 nfa_t4tnfcee_cb.status = NFA_STATUS_FAILED;
164 nfa_t4tnfcee_notify_rx_evt();
165 }
166 break;
167 }
168 case NFA_T4TNFCEE_OP_CLOSE_CONNECTION: {
169 LOG(DEBUG) << StringPrintf("%s: NFA_T4TNFCEE_OP_CLOSE_CONNECTION",
170 __func__);
171 nfa_t4tnfcee_proc_disc_evt(NFA_T4TNFCEE_OP_CLOSE_CONNECTION);
172 } break;
173 default:
174 break;
175 }
176 return true;
177 }
178 /*******************************************************************************
179 **
180 ** Function nfa_t4tnfcee_check_sw
181 **
182 ** Description Updates the status if R-APDU has been received with failure
183 *status
184 **
185 ** Returns Nothing
186 **
187 *******************************************************************************/
nfa_t4tnfcee_check_sw(tRW_DATA * p_rwData)188 static void nfa_t4tnfcee_check_sw(tRW_DATA* p_rwData) {
189 uint8_t* p;
190 uint16_t status_words;
191 NFC_HDR* p_r_apdu = p_rwData->raw_frame.p_data;
192 p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
193 p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
194 BE_STREAM_TO_UINT16(status_words, p);
195 if ((status_words != T4T_RSP_CMD_CMPLTED) &&
196 (!T4T_RSP_WARNING_PARAMS_CHECK(status_words >> 8))) {
197 p_rwData->raw_frame.status = NFC_STATUS_FAILED;
198 LOG(DEBUG) << StringPrintf("%s: status 0x%X", __func__, status_words);
199 }
200 }
201 /*******************************************************************************
202 **
203 ** Function nfa_t4tnfcee_handle_t4t_evt
204 **
205 ** Description Handler for Type-4 NFCEE reader/writer events
206 **
207 ** Returns Nothing
208 **
209 *******************************************************************************/
nfa_t4tnfcee_handle_t4t_evt(tRW_EVENT event,tRW_DATA * p_rwData)210 void nfa_t4tnfcee_handle_t4t_evt(tRW_EVENT event, tRW_DATA* p_rwData) {
211 LOG(DEBUG) << StringPrintf("%s: event=0x%02x 0x%02x", __func__, event,
212 p_rwData->status);
213 switch (event) {
214 case RW_T4T_RAW_FRAME_EVT:
215 nfa_t4tnfcee_check_sw(p_rwData);
216 LOG(DEBUG) << StringPrintf("%s: RW_T4T_RAW_FRAME_EVT", __func__);
217 nfa_t4tnfcee_handle_file_operations(p_rwData);
218 break;
219 case RW_T4T_INTF_ERROR_EVT:
220 LOG(DEBUG) << StringPrintf("%s: RW_T4T_INTF_ERROR_EVT", __func__);
221 nfa_t4tnfcee_handle_file_operations(p_rwData);
222 break;
223 default:
224 LOG(DEBUG) << StringPrintf("%s: UNKNOWN EVENT", __func__);
225 break;
226 }
227 return;
228 }
229
230 /*******************************************************************************
231 **
232 ** Function nfa_t4tnfcee_store_cc_info
233 **
234 ** Description stores CC info into local data structure
235 **
236 ** Returns Nothing
237 **
238 *******************************************************************************/
nfa_t4tnfcee_store_cc_info(NFC_HDR * p_data)239 void nfa_t4tnfcee_store_cc_info(NFC_HDR* p_data) {
240 LOG(DEBUG) << StringPrintf("%s", __func__);
241
242 uint16_t keyFileId;
243 string valueFileLength;
244 const uint8_t skipTL = 0x02, tlvLen = 0x08;
245 uint8_t jumpToFirstTLV = 0x03; /*Le index*/
246 uint16_t RemainingDataLen = 0;
247 uint8_t* ccInfo;
248
249 if (NULL != p_data) {
250 if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ_CC_FILE) {
251 ccInfo = (uint8_t*)(p_data + 1) +
252 p_data->offset; // CC data does not require NDEF header offset
253 nfa_t4tnfcee_cb.p_dataBuf = (uint8_t*)nfa_mem_co_alloc(p_data->len);
254 memcpy(&nfa_t4tnfcee_cb.p_dataBuf[0], ccInfo, p_data->len);
255 return;
256 } else {
257 ccInfo = (uint8_t*)(p_data + 1) + p_data->offset + jumpToFirstTLV;
258 }
259 } else {
260 LOG(DEBUG) << StringPrintf("%s: empty cc info", __func__);
261 return;
262 }
263 RW_T4tNfceeUpdateCC(ccInfo);
264
265 jumpToFirstTLV = 0x07;
266 ccInfo = (uint8_t*)(p_data + 1) + p_data->offset + jumpToFirstTLV;
267 ccFileInfo.clear();
268 RemainingDataLen =
269 (p_data->len - jumpToFirstTLV - T4TNFCEE_SIZEOF_STATUS_BYTES);
270 while (RemainingDataLen >= 0x08) {
271 tNFA_T4TNFCEE_FILE_INFO fileInfo;
272 ccInfo += skipTL;
273 BE_STREAM_TO_UINT16(keyFileId, ccInfo);
274 BE_STREAM_TO_UINT16(fileInfo.capacity, ccInfo);
275 BE_STREAM_TO_UINT8(fileInfo.read_access, ccInfo);
276 BE_STREAM_TO_UINT8(fileInfo.write_access, ccInfo);
277 ccFileInfo.insert(
278 pair<uint16_t, tNFA_T4TNFCEE_FILE_INFO>(keyFileId, fileInfo));
279 keyFileId = 0x00;
280 RemainingDataLen -= tlvLen;
281 }
282 }
283
284 /*******************************************************************************
285 **
286 ** Function nfa_t4tnfcee_store_rx_buf
287 **
288 ** Description Stores read data.
289 **
290 ** Returns Nothing
291 **
292 *******************************************************************************/
nfa_t4tnfcee_store_rx_buf(NFC_HDR * p_data)293 void nfa_t4tnfcee_store_rx_buf(NFC_HDR* p_data) {
294 uint8_t* p;
295 if (NULL != p_data) {
296 LOG(DEBUG) << StringPrintf("%s: copying data len %d rd_offset=%d",
297 __func__, p_data->len,
298 nfa_t4tnfcee_cb.rd_offset);
299 p = (uint8_t*)(p_data + 1) + p_data->offset;
300 memcpy(&nfa_t4tnfcee_cb.p_dataBuf[nfa_t4tnfcee_cb.rd_offset], p,
301 p_data->len);
302 nfa_t4tnfcee_cb.rd_offset += p_data->len;
303 } else {
304 LOG(DEBUG) << StringPrintf("%s: Data is NULL", __func__);
305 }
306 }
307
308 /*******************************************************************************
309 **
310 ** Function nfa_t4tnfcee_initialize_data
311 **
312 ** Description Initializes control block
313 **
314 ** Returns none
315 **
316 *******************************************************************************/
nfa_t4tnfcee_initialize_data(tNFA_T4TNFCEE_MSG * p_data)317 void nfa_t4tnfcee_initialize_data(tNFA_T4TNFCEE_MSG* p_data) {
318 nfa_t4tnfcee_cb.rw_state = PROP_DISABLED;
319 nfa_t4tnfcee_cb.rd_offset = 0;
320 nfa_t4tnfcee_cb.p_dataBuf = nullptr;
321 nfa_t4tnfcee_cb.dataLen = 0x00;
322 BE_STREAM_TO_UINT16(nfa_t4tnfcee_cb.cur_fileId, p_data->op_req.p_fileId);
323 }
324 /*******************************************************************************
325 **
326 ** Function nfa_t4tnfcee_handle_file_operations
327 **
328 ** Description Handles proprietary file operations
329 **
330 ** Returns none
331 **
332 *******************************************************************************/
nfa_t4tnfcee_handle_file_operations(tRW_DATA * p_rwData)333 void nfa_t4tnfcee_handle_file_operations(tRW_DATA* p_rwData) {
334 if (p_rwData == nullptr) {
335 nfa_t4tnfcee_cb.status = NFC_STATUS_FAILED;
336 nfa_t4tnfcee_notify_rx_evt();
337 return;
338 }
339 LOG(DEBUG) << StringPrintf("%s: currState=0x%02x", __func__,
340 nfa_t4tnfcee_cb.rw_state);
341 switch (nfa_t4tnfcee_cb.rw_state) {
342 case WAIT_SELECT_APPLICATION:
343 if (isError(p_rwData->raw_frame.status)) break;
344 RW_T4tNfceeSelectFile(CC_FILE_ID);
345 nfa_t4tnfcee_cb.rw_state = WAIT_SELECT_CC;
346 break;
347
348 case WAIT_SELECT_CC:
349 if (isError(p_rwData->raw_frame.status)) break;
350 RW_T4tNfceeReadDataLen();
351 nfa_t4tnfcee_cb.rw_state = WAIT_READ_CC_DATA_LEN;
352 break;
353
354 case WAIT_READ_CC_DATA_LEN: {
355 if (isError(p_rwData->raw_frame.status)) break;
356 uint16_t lenDataToBeRead = nfa_t4tnfcee_get_len(p_rwData);
357 if (lenDataToBeRead <= 0x00) {
358 nfa_t4tnfcee_cb.status = NFC_STATUS_NO_BUFFERS;
359 nfa_t4tnfcee_notify_rx_evt();
360 break;
361 }
362 RW_T4tNfceeReadFile(0x00, lenDataToBeRead);
363 nfa_t4tnfcee_cb.rw_state = WAIT_READ_CC_FILE;
364 break;
365 }
366
367 case WAIT_READ_CC_FILE: {
368 if (isError(p_rwData->raw_frame.status)) break;
369 nfa_t4tnfcee_store_cc_info(p_rwData->raw_frame.p_data);
370 if (nfa_t4tnfcee_cb.cur_op != NFA_T4TNFCEE_OP_READ_CC_FILE) {
371 if (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId) == ccFileInfo.end()) {
372 LOG(DEBUG) << StringPrintf("%s: FileId Not found in CC", __func__);
373 nfa_t4tnfcee_cb.status = NFA_T4T_STATUS_INVALID_FILE_ID;
374 nfa_t4tnfcee_notify_rx_evt();
375 break;
376 }
377 } else {
378 nfa_t4tnfcee_cb.dataLen = p_rwData->raw_frame.p_data->len;
379 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
380 nfa_t4tnfcee_notify_rx_evt();
381 break;
382 }
383 RW_T4tNfceeSelectFile(nfa_t4tnfcee_cb.cur_fileId);
384 nfa_t4tnfcee_cb.rw_state = WAIT_SELECT_FILE;
385 break;
386 }
387
388 case WAIT_SELECT_FILE: {
389 if (isError(p_rwData->raw_frame.status)) break;
390 if ((nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ) &&
391 isReadPermitted()) {
392 RW_T4tNfceeReadDataLen();
393 nfa_t4tnfcee_cb.rw_state = WAIT_READ_DATA_LEN;
394 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_WRITE) {
395 tNFA_STATUS preCondStatus = getWritePreconditionStatus();
396 if (preCondStatus == NFA_STATUS_OK) {
397 RW_T4tNfceeUpdateNlen(0x0000);
398 nfa_t4tnfcee_cb.rw_state = WAIT_RESET_NLEN;
399 } else {
400 nfa_t4tnfcee_cb.status = preCondStatus;
401 nfa_t4tnfcee_notify_rx_evt();
402 }
403 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_CLEAR) {
404 RW_T4tNfceeReadDataLen();
405 nfa_t4tnfcee_cb.rw_state = WAIT_CLEAR_NDEF_DATA;
406 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ_CC_FILE) {
407 nfa_t4tnfcee_cb.dataLen = nfa_t4tnfcee_cb.rd_offset;
408 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
409 nfa_t4tnfcee_notify_rx_evt();
410 }
411 break;
412 }
413
414 case WAIT_CLEAR_NDEF_DATA: {
415 if (isError(p_rwData->raw_frame.status)) break;
416 uint16_t lenDataToBeClear = nfa_t4tnfcee_get_len(p_rwData);
417 if (lenDataToBeClear == 0x00) {
418 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
419 nfa_t4tnfcee_notify_rx_evt();
420 break;
421 }
422 RW_T4tNfceeUpdateNlen(0x0000);
423 nfa_t4tnfcee_cb.p_dataBuf = (uint8_t*)nfa_mem_co_alloc(lenDataToBeClear);
424 if (!nfa_t4tnfcee_cb.p_dataBuf) {
425 nfa_t4tnfcee_cb.status = NFC_STATUS_FAILED;
426 nfa_t4tnfcee_notify_rx_evt();
427 break;
428 }
429 memset(nfa_t4tnfcee_cb.p_dataBuf, 0, lenDataToBeClear);
430 nfa_t4tnfcee_cb.dataLen = lenDataToBeClear;
431 nfa_t4tnfcee_cb.rw_state = WAIT_RESET_NLEN;
432 break;
433 }
434
435 case WAIT_READ_DATA_LEN: {
436 if (isError(p_rwData->raw_frame.status)) break;
437 uint16_t lenDataToBeRead = nfa_t4tnfcee_get_len(p_rwData);
438 if (lenDataToBeRead <= 0x00) {
439 nfa_t4tnfcee_cb.status = NFC_STATUS_NO_BUFFERS;
440 nfa_t4tnfcee_notify_rx_evt();
441 break;
442 }
443
444 nfa_t4tnfcee_cb.p_dataBuf = (uint8_t*)nfa_mem_co_alloc(lenDataToBeRead);
445 RW_T4tNfceeReadFile(T4T_FILE_LENGTH_SIZE, lenDataToBeRead);
446 nfa_t4tnfcee_cb.rw_state = WAIT_READ_FILE;
447 break;
448 }
449
450 case WAIT_READ_FILE: {
451 if (isError(p_rwData->raw_frame.status)) break;
452 /*updating length field to discard status while processing read data
453 For RAW data, T4T module returns length including status length*/
454 if (p_rwData->raw_frame.p_data->len >= T4T_FILE_LENGTH_SIZE)
455 p_rwData->raw_frame.p_data->len -= T4T_FILE_LENGTH_SIZE;
456 nfa_t4tnfcee_store_rx_buf(p_rwData->raw_frame.p_data);
457 if (RW_T4tIsReadComplete()) {
458 nfa_t4tnfcee_cb.dataLen = nfa_t4tnfcee_cb.rd_offset;
459 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
460 nfa_t4tnfcee_notify_rx_evt();
461 } else {
462 RW_T4tNfceeReadPendingData();
463 }
464 break;
465 }
466
467 case WAIT_RESET_NLEN: {
468 if (isError(p_rwData->raw_frame.status)) break;
469 RW_T4tNfceeStartUpdateFile(nfa_t4tnfcee_cb.dataLen,
470 nfa_t4tnfcee_cb.p_dataBuf);
471 if (RW_T4tIsUpdateComplete())
472 nfa_t4tnfcee_cb.rw_state = WAIT_WRITE_COMPLETE;
473 else
474 nfa_t4tnfcee_cb.rw_state = WAIT_WRITE;
475 break;
476 }
477
478 case WAIT_WRITE: {
479 RW_T4tNfceeUpdateFile();
480 if (RW_T4tIsUpdateComplete())
481 nfa_t4tnfcee_cb.rw_state = WAIT_WRITE_COMPLETE;
482 break;
483 }
484
485 case WAIT_WRITE_COMPLETE: {
486 if (isError(p_rwData->raw_frame.status)) break;
487 if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_CLEAR) {
488 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
489 /*Length is already zero returning from here.*/
490 nfa_t4tnfcee_notify_rx_evt();
491 } else {
492 RW_T4tNfceeUpdateNlen(nfa_t4tnfcee_cb.dataLen);
493 nfa_t4tnfcee_cb.rw_state = WAIT_UPDATE_NLEN;
494 }
495 break;
496 }
497
498 case WAIT_UPDATE_NLEN: {
499 if (isError(p_rwData->raw_frame.status)) break;
500 nfa_t4tnfcee_cb.status = p_rwData->raw_frame.status;
501 nfa_t4tnfcee_notify_rx_evt();
502 break;
503 }
504
505 default:
506 break;
507 }
508 GKI_freebuf(p_rwData->raw_frame.p_data);
509 }
510 /*******************************************************************************
511 **
512 ** Function nfa_t4tnfcee_notify_rx_evt
513 **
514 ** Description Notifies to upper layer with data
515 **
516 ** Returns None
517 **
518 *******************************************************************************/
nfa_t4tnfcee_notify_rx_evt(void)519 void nfa_t4tnfcee_notify_rx_evt(void) {
520 tNFA_CONN_EVT_DATA conn_evt_data;
521 conn_evt_data.status = nfa_t4tnfcee_cb.status;
522 nfa_t4tnfcee_cb.rw_state = OP_COMPLETE;
523 if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ) {
524 if (conn_evt_data.status == NFA_STATUS_OK) {
525 conn_evt_data.data.p_data = nfa_t4tnfcee_cb.p_dataBuf;
526 conn_evt_data.data.len = nfa_t4tnfcee_cb.dataLen;
527 }
528 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_READ_CPLT_EVT, &conn_evt_data);
529 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_WRITE) {
530 if (conn_evt_data.status == NFA_STATUS_OK) {
531 conn_evt_data.data.len = nfa_t4tnfcee_cb.dataLen;
532 }
533 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_WRITE_CPLT_EVT, &conn_evt_data);
534 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_CLEAR) {
535 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_CLEAR_CPLT_EVT, &conn_evt_data);
536 } else if (nfa_t4tnfcee_cb.cur_op == NFA_T4TNFCEE_OP_READ_CC_FILE) {
537 if (conn_evt_data.status == NFA_STATUS_OK) {
538 conn_evt_data.data.p_data = nfa_t4tnfcee_cb.p_dataBuf;
539 conn_evt_data.data.len = nfa_t4tnfcee_cb.dataLen;
540 }
541 nfa_dm_act_conn_cback_notify(NFA_T4TNFCEE_READ_CC_DATA_CPLT_EVT,
542 &conn_evt_data);
543 }
544 nfa_t4tnfcee_free_rx_buf();
545 }
546
547 /*******************************************************************************
548 **
549 ** Function is_read_precondition_valid
550 **
551 ** Description validates precondition for read
552 **
553 ** Returns true/false
554 **
555 *******************************************************************************/
is_read_precondition_valid(tNFA_T4TNFCEE_MSG * p_data)556 bool is_read_precondition_valid(tNFA_T4TNFCEE_MSG* p_data) {
557 if ((p_data->op_req.p_fileId == nullptr) ||
558 (nfa_t4tnfcee_cb.t4tnfcee_state != NFA_T4TNFCEE_STATE_CONNECTED)) {
559 return false;
560 }
561 return true;
562 }
563
564 /*******************************************************************************
565 **
566 ** Function is_write_precondition_valid
567 **
568 ** Description validates precondition for write
569 **
570 ** Returns true/false
571 **
572 *******************************************************************************/
is_write_precondition_valid(tNFA_T4TNFCEE_MSG * p_data)573 bool is_write_precondition_valid(tNFA_T4TNFCEE_MSG* p_data) {
574 if ((p_data->op_req.p_fileId == nullptr) ||
575 (nfa_t4tnfcee_cb.t4tnfcee_state != NFA_T4TNFCEE_STATE_CONNECTED) ||
576 (p_data->op_req.write.p_data == nullptr) ||
577 (p_data->op_req.write.len == 0)) {
578 return false;
579 }
580 return true;
581 }
582
583 /*******************************************************************************
584 **
585 ** Function isReadPermitted
586 **
587 ** Description Checks if read permitted for current file
588 **
589 ** Returns true/false
590 **
591 *******************************************************************************/
isReadPermitted(void)592 bool isReadPermitted(void) {
593 if (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId) == ccFileInfo.end()) {
594 LOG(ERROR) << StringPrintf("%s: FileId Not found", __func__);
595 return false;
596 }
597 return (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId)->second.read_access ==
598 T4T_NFCEE_READ_ALLOWED);
599 }
600
601 /*******************************************************************************
602 **
603 ** Function isWritePermitted
604 **
605 ** Description Checks if write permitted for current file
606 **
607 ** Returns true/false
608 **
609 *******************************************************************************/
isWritePermitted(void)610 bool isWritePermitted(void) {
611 if (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId) == ccFileInfo.end()) {
612 LOG(ERROR) << StringPrintf("%s: FileId Not found", __func__);
613 return false;
614 }
615 LOG(DEBUG) << StringPrintf(
616 "%s: 0x%2x", __func__,
617 ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId)->second.write_access);
618 return ((ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId)->second.write_access !=
619 T4T_NFCEE_WRITE_NOT_ALLOWED));
620 }
621
622 /*******************************************************************************
623 **
624 ** Function isDataLenBelowMaxFileCapacity
625 **
626 ** Description Checks if current data length is less not exceeding file
627 ** capacity
628 **
629 ** Returns true/false
630 **
631 *******************************************************************************/
isDataLenBelowMaxFileCapacity(void)632 bool isDataLenBelowMaxFileCapacity(void) {
633 if (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId) == ccFileInfo.end()) {
634 LOG(ERROR) << StringPrintf("%s: FileId Not found", __func__);
635 return false;
636 }
637 return (nfa_t4tnfcee_cb.dataLen <=
638 (ccFileInfo.find(nfa_t4tnfcee_cb.cur_fileId)->second.capacity -
639 T4TNFCEE_SIZEOF_LEN_BYTES));
640 }
641
642 /*******************************************************************************
643 **
644 ** Function getWritePreconditionStatus
645 **
646 ** Description Checks if write preconditions are satisfied
647 **
648 ** Returns NFA_STATUS_OK if success else ERROR status
649 **
650 *******************************************************************************/
getWritePreconditionStatus()651 tNFC_STATUS getWritePreconditionStatus() {
652 if (!isWritePermitted()) return NCI_STATUS_READ_ONLY;
653 if (!isDataLenBelowMaxFileCapacity()) {
654 LOG(ERROR) << StringPrintf("%s: Data Len exceeds max file size", __func__);
655 return NFA_STATUS_FAILED;
656 }
657 if (nfa_t4tnfcee_cb.cur_fileId == NDEF_FILE_ID) {
658 tNDEF_STATUS ndef_status;
659 if ((ndef_status = NDEF_MsgValidate(nfa_t4tnfcee_cb.p_dataBuf,
660 nfa_t4tnfcee_cb.dataLen, true)) !=
661 NDEF_OK) {
662 LOG(DEBUG) << StringPrintf(
663 "%s: Invalid NDEF message. NDEF_MsgValidate returned %i", __func__,
664 ndef_status);
665 return NFA_STATUS_REJECTED;
666 }
667 /*NDEF Msg validation SUCCESS*/
668 return NFA_STATUS_OK;
669 }
670 return NFA_STATUS_OK;
671 }
672
673 /*******************************************************************************
674 **
675 ** Function nfa_t4tnfcee_get_len
676 **
677 ** Description get the length of data available in current selected file
678 **
679 ** Returns data len
680 **
681 *******************************************************************************/
nfa_t4tnfcee_get_len(tRW_DATA * p_rwData)682 uint16_t nfa_t4tnfcee_get_len(tRW_DATA* p_rwData) {
683 uint8_t* p = nullptr;
684 uint16_t readLen = 0x00;
685 if (p_rwData->raw_frame.p_data->len > 0x00) {
686 p = (uint8_t*)(p_rwData->raw_frame.p_data + 1) +
687 p_rwData->raw_frame.p_data->offset;
688 }
689 if (p != nullptr) BE_STREAM_TO_UINT16(readLen, p);
690 if (readLen > 0x00) {
691 LOG(DEBUG) << StringPrintf("%s: readLen 0x%x", __func__, readLen);
692 } else {
693 LOG(DEBUG) << StringPrintf("%s: No Data to Read", __func__);
694 }
695 return readLen;
696 }
697
698 /*******************************************************************************
699 **
700 ** Function isError
701 **
702 ** Description Checks and notifies upper layer in case of error
703 **
704 ** Returns true if error else false
705 **
706 *******************************************************************************/
isError(tNFC_STATUS status)707 bool isError(tNFC_STATUS status) {
708 if (status != NFA_STATUS_OK) {
709 nfa_t4tnfcee_cb.status = NFC_STATUS_FAILED;
710 nfa_t4tnfcee_notify_rx_evt();
711 return true;
712 } else
713 return false;
714 }
715