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