• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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