xref: /aosp_15_r20/system/nfc/src/nfa/ndefnfcee/t4t/nfa_nfcee_act.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
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