1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the action functions the NFA_RW state machine.
22  *
23  ******************************************************************************/
24 #include <string.h>
25 
26 #include <android-base/stringprintf.h>
27 #include <base/logging.h>
28 
29 #include "ndef_utils.h"
30 #include "nfa_dm_int.h"
31 #include "nfa_mem_co.h"
32 #include "nfa_rw_int.h"
33 
34 using android::base::StringPrintf;
35 
36 extern bool nfc_debug_enabled;
37 
38 #define NFA_RW_OPTION_INVALID 0xFF
39 
40 /* Tag sleep req cmd*/
41 uint8_t NFA_RW_TAG_SLP_REQ[] = {0x50, 0x00};
42 
43 /* Local static function prototypes */
44 static tNFC_STATUS nfa_rw_start_ndef_read(void);
45 static tNFC_STATUS nfa_rw_start_ndef_write(void);
46 static tNFC_STATUS nfa_rw_start_ndef_detection(void);
47 static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock);
48 static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data);
49 static void nfa_rw_error_cleanup(uint8_t event);
50 static void nfa_rw_presence_check(tNFA_RW_MSG* p_data);
51 static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data);
52 static bool nfa_rw_detect_ndef(void);
53 static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data);
54 
55 /*******************************************************************************
56 **
57 ** Function         nfa_rw_free_ndef_rx_buf
58 **
59 ** Description      Free buffer allocated to hold incoming NDEF message
60 **
61 ** Returns          Nothing
62 **
63 *******************************************************************************/
nfa_rw_free_ndef_rx_buf(void)64 void nfa_rw_free_ndef_rx_buf(void) {
65   if (nfa_rw_cb.p_ndef_buf) {
66     nfa_mem_co_free(nfa_rw_cb.p_ndef_buf);
67     nfa_rw_cb.p_ndef_buf = NULL;
68   }
69 }
70 
71 /*******************************************************************************
72 **
73 ** Function         nfa_rw_store_ndef_rx_buf
74 **
75 ** Description      Store data into NDEF buffer
76 **
77 ** Returns          Nothing
78 **
79 *******************************************************************************/
nfa_rw_store_ndef_rx_buf(tRW_DATA * p_rw_data)80 static void nfa_rw_store_ndef_rx_buf(tRW_DATA* p_rw_data) {
81   uint8_t* p;
82 
83   p = (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
84 
85   /* Save data into buffer */
86   memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p,
87          p_rw_data->data.p_data->len);
88   nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len;
89 
90   GKI_freebuf(p_rw_data->data.p_data);
91   p_rw_data->data.p_data = NULL;
92 }
93 
94 /*******************************************************************************
95 **
96 ** Function         nfa_rw_send_data_to_upper
97 **
98 ** Description      Send data to upper layer
99 **
100 ** Returns          Nothing
101 **
102 *******************************************************************************/
nfa_rw_send_data_to_upper(tRW_DATA * p_rw_data)103 static void nfa_rw_send_data_to_upper(tRW_DATA* p_rw_data) {
104   tNFA_CONN_EVT_DATA conn_evt_data;
105 
106   if ((p_rw_data->status == NFC_STATUS_TIMEOUT) ||
107       (p_rw_data->data.p_data == NULL))
108     return;
109 
110   DLOG_IF(INFO, nfc_debug_enabled)
111       << StringPrintf("nfa_rw_send_data_to_upper: Len [0x%X] Status [%s]",
112                       p_rw_data->data.p_data->len,
113                       NFC_GetStatusName(p_rw_data->data.status).c_str());
114 
115   /* Notify conn cback of NFA_DATA_EVT */
116   conn_evt_data.data.status = p_rw_data->data.status;
117   conn_evt_data.data.p_data =
118       (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
119   conn_evt_data.data.len = p_rw_data->data.p_data->len;
120 
121   nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
122 
123   GKI_freebuf(p_rw_data->data.p_data);
124   p_rw_data->data.p_data = NULL;
125 }
126 
127 /*******************************************************************************
128 **
129 ** Function         nfa_rw_error_cleanup
130 **
131 ** Description      Handle failure - signal command complete and notify app
132 **
133 ** Returns          Nothing
134 **
135 *******************************************************************************/
nfa_rw_error_cleanup(uint8_t event)136 static void nfa_rw_error_cleanup(uint8_t event) {
137   tNFA_CONN_EVT_DATA conn_evt_data;
138 
139   nfa_rw_command_complete();
140 
141   conn_evt_data.status = NFA_STATUS_FAILED;
142 
143   nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
144 }
145 
146 /*******************************************************************************
147 **
148 ** Function         nfa_rw_check_start_presence_check_timer
149 **
150 ** Description      Start timer to wait for specified time before presence check
151 **
152 ** Returns          Nothing
153 **
154 *******************************************************************************/
nfa_rw_check_start_presence_check_timer(uint16_t presence_check_start_delay)155 static void nfa_rw_check_start_presence_check_timer(
156     uint16_t presence_check_start_delay) {
157   if (!p_nfa_dm_cfg->auto_presence_check) return;
158 
159   if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) {
160     if (presence_check_start_delay) {
161       DLOG_IF(INFO, nfc_debug_enabled)
162           << StringPrintf("Starting presence check timer...");
163       nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT,
164                           presence_check_start_delay);
165     } else {
166       /* Presence check now */
167       nfa_rw_presence_check(NULL);
168     }
169   }
170 }
171 
172 /*******************************************************************************
173 **
174 ** Function         nfa_rw_stop_presence_check_timer
175 **
176 ** Description      Stop timer for presence check
177 **
178 ** Returns          Nothing
179 **
180 *******************************************************************************/
nfa_rw_stop_presence_check_timer(void)181 void nfa_rw_stop_presence_check_timer(void) {
182   nfa_sys_stop_timer(&nfa_rw_cb.tle);
183   DLOG_IF(INFO, nfc_debug_enabled)
184       << StringPrintf("Stopped presence check timer (if started)");
185 }
186 
187 /*******************************************************************************
188 **
189 ** Function         nfa_rw_handle_ndef_detect
190 **
191 ** Description      Handler for NDEF detection reader/writer event
192 **
193 ** Returns          Nothing
194 **
195 *******************************************************************************/
nfa_rw_handle_ndef_detect(tRW_DATA * p_rw_data)196 static void nfa_rw_handle_ndef_detect(tRW_DATA* p_rw_data) {
197   tNFA_CONN_EVT_DATA conn_evt_data;
198 
199   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
200       "NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x",
201       p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size,
202       p_rw_data->ndef.flags);
203 
204   /* Check if NDEF detection succeeded */
205   if (p_rw_data->ndef.status == NFC_STATUS_OK) {
206     /* Set NDEF detection state */
207     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE;
208     nfa_rw_cb.flags |= NFA_RW_FL_NDEF_OK;
209 
210     /* Store ndef properties */
211     conn_evt_data.ndef_detect.status = NFA_STATUS_OK;
212     conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
213     conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
214         p_rw_data->ndef.cur_size;
215     conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
216         p_rw_data->ndef.max_size;
217     conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
218 
219     if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY)
220       nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
221     else
222       nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY;
223 
224     /* Determine what operation triggered the NDEF detection procedure */
225     if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
226       /* if ndef detection was done as part of ndef-read operation, then perform
227        * ndef read now */
228       conn_evt_data.status = nfa_rw_start_ndef_read();
229       if (conn_evt_data.status != NFA_STATUS_OK) {
230         /* Failed to start NDEF Read */
231 
232         /* Command complete - perform cleanup, notify app */
233         nfa_rw_command_complete();
234         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
235       }
236     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
237       /* if ndef detection was done as part of ndef-write operation, then
238        * perform ndef write now */
239       conn_evt_data.status = nfa_rw_start_ndef_write();
240       if (conn_evt_data.status != NFA_STATUS_OK) {
241         /* Failed to start NDEF Write.  */
242 
243         /* Command complete - perform cleanup, notify app */
244         nfa_rw_command_complete();
245         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
246       }
247     } else {
248       /* current op was stand-alone NFA_DetectNDef. Command complete - perform
249        * cleanup and notify app */
250       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
251       nfa_rw_command_complete();
252 
253       nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
254     }
255   } else {
256     /* NDEF detection failed... */
257 
258     /* Command complete - perform cleanup, notify app */
259     nfa_rw_command_complete();
260     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
261     conn_evt_data.status = p_rw_data->ndef.status;
262 
263     if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
264       /* if ndef detection was done as part of ndef-read operation, then notify
265        * NDEF handlers of failure */
266       nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
267 
268       /* Notify app of read status */
269       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
270     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
271       /* if ndef detection was done as part of ndef-write operation, then notify
272        * app of failure */
273       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
274     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) {
275       conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
276       /* current op was stand-alone NFA_DetectNDef. Notify app of failure */
277       if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT) {
278         /* Tag could have moved away */
279         conn_evt_data.ndef_detect.cur_size = 0;
280         conn_evt_data.ndef_detect.max_size = 0;
281         conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
282         conn_evt_data.ndef_detect.status = NFA_STATUS_TIMEOUT;
283       } else {
284         /* NDEF Detection failed for other reasons */
285         conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
286             p_rw_data->ndef.cur_size;
287         conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
288             p_rw_data->ndef.max_size;
289         conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
290       }
291       nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
292     }
293 
294     nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
295   }
296 }
297 
298 /*******************************************************************************
299 **
300 ** Function         nfa_rw_handle_tlv_detect
301 **
302 ** Description      Handler for TLV detection reader/writer event
303 **
304 ** Returns          Nothing
305 **
306 *******************************************************************************/
nfa_rw_handle_tlv_detect(tRW_DATA * p_rw_data)307 static void nfa_rw_handle_tlv_detect(tRW_DATA* p_rw_data) {
308   tNFA_CONN_EVT_DATA conn_evt_data;
309 
310   /* Set TLV detection state */
311   if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
312     if (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) {
313       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
314     } else {
315       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
316     }
317   } else {
318     if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) {
319       nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
320     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) {
321       nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
322     }
323   }
324 
325   /* Check if TLV detection succeeded */
326   if (p_rw_data->tlv.status == NFC_STATUS_OK) {
327     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
328         "TLV Detection succeeded: num_bytes=%i", p_rw_data->tlv.num_bytes);
329 
330     /* Store tlv properties */
331     conn_evt_data.tlv_detect.status = NFA_STATUS_OK;
332     conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol;
333     conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes;
334 
335     /* Determine what operation triggered the TLV detection procedure */
336     if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
337       if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
338         /* Failed to set tag read only */
339         conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
340         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
341       }
342     } else {
343       /* current op was stand-alone NFA_DetectTlv. Command complete - perform
344        * cleanup and notify app */
345       nfa_rw_command_complete();
346       nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
347     }
348   }
349 
350   /* Handle failures */
351   if (p_rw_data->tlv.status != NFC_STATUS_OK) {
352     /* Command complete - perform cleanup, notify the app */
353     nfa_rw_command_complete();
354 
355     conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
356     if ((nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) ||
357         (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)) {
358       nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
359     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
360       if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
361         /* Failed to set tag read only */
362         conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
363         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
364       }
365     }
366   }
367 }
368 
369 /*******************************************************************************
370 **
371 ** Function         nfa_rw_handle_sleep_wakeup_rsp
372 **
373 ** Description      Handl sleep wakeup
374 **
375 ** Returns          Nothing
376 **
377 *******************************************************************************/
nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status)378 void nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status) {
379   tNFC_ACTIVATE_DEVT activate_params;
380   tRW_EVENT event;
381 
382   if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
383       (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
384       (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
385       (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
386     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
387         "nfa_rw_handle_sleep_wakeup_rsp; Attempt to wake up Type 2 tag from "
388         "HALT State is complete");
389     if (status == NFC_STATUS_OK) {
390       /* Type 2 Tag is wakeup from HALT state */
391       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
392           "nfa_rw_handle_sleep_wakeup_rsp; Handle the NACK rsp received now");
393       /* Initialize control block */
394       activate_params.protocol = nfa_rw_cb.protocol;
395       activate_params.rf_tech_param.param.pa.sel_rsp = nfa_rw_cb.pa_sel_res;
396       activate_params.rf_tech_param.mode = nfa_rw_cb.activated_tech_mode;
397 
398       /* Initialize RW module */
399       if ((RW_SetActivatedTagType(&activate_params, nfa_rw_cback)) !=
400           NFC_STATUS_OK) {
401         /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
402         LOG(ERROR) << StringPrintf("RW_SetActivatedTagType failed.");
403         if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
404           if (nfa_rw_cb.rw_data.data.p_data)
405             GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
406           nfa_rw_cb.rw_data.data.p_data = NULL;
407         }
408         /* Do not try to detect NDEF again but just notify current operation
409          * failed */
410         nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
411       }
412     }
413 
414     /* The current operation failed with NACK rsp from type 2 tag */
415     nfa_rw_cb.rw_data.status = NFC_STATUS_FAILED;
416     event = nfa_rw_cb.halt_event;
417 
418     /* Got NACK rsp during presence check and legacy presence check performed */
419     if (nfa_rw_cb.cur_op == NFA_RW_OP_PRESENCE_CHECK)
420       nfa_rw_cb.rw_data.status = status;
421 
422     /* If cannot Sleep wakeup tag, then NDEF Detect operation is complete */
423     if ((status != NFC_STATUS_OK) &&
424         (nfa_rw_cb.halt_event == RW_T2T_NDEF_DETECT_EVT))
425       nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
426 
427     nfa_rw_handle_t2t_evt(event, &nfa_rw_cb.rw_data);
428     nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
429 
430     /* If Type 2 tag sleep wakeup failed and If in normal mode (not-exclusive RF
431      * mode) then deactivate the link if sleep wakeup failed */
432     if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
433         (status != NFC_STATUS_OK)) {
434       DLOG_IF(INFO, nfc_debug_enabled)
435           << StringPrintf("Sleep wakeup failed. Deactivating...");
436       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
437     }
438   } else {
439     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
440         "nfa_rw_handle_sleep_wakeup_rsp; Legacy presence check performed");
441     /* Legacy presence check performed */
442     nfa_rw_handle_presence_check_rsp(status);
443   }
444 }
445 
446 /*******************************************************************************
447 **
448 ** Function         nfa_rw_handle_presence_check_rsp
449 **
450 ** Description      Handler RW_T#t_PRESENCE_CHECK_EVT
451 **
452 ** Returns          Nothing
453 **
454 *******************************************************************************/
nfa_rw_handle_presence_check_rsp(tNFC_STATUS status)455 void nfa_rw_handle_presence_check_rsp(tNFC_STATUS status) {
456   NFC_HDR* p_pending_msg;
457 
458   /* Stop the presence check timer - timer may have been started when presence
459    * check started */
460   nfa_rw_stop_presence_check_timer();
461   if (status == NFA_STATUS_OK) {
462     /* Clear the BUSY flag and restart the presence-check timer */
463     nfa_rw_command_complete();
464   } else {
465     /* If presence check failed just clear the BUSY flag */
466     nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
467   }
468 
469   /* Handle presence check due to auto-presence-check  */
470   if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
471     nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
472 
473     /* If an API was called during auto-presence-check, then handle it now */
474     if (nfa_rw_cb.p_pending_msg) {
475       /* If NFA_RwPresenceCheck was called during auto-presence-check, notify
476        * app of result */
477       if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK) {
478         /* Notify app of presence check status */
479         tNFA_CONN_EVT_DATA nfa_conn_evt_data;
480         nfa_conn_evt_data.status = status;
481         nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT,
482                                      &nfa_conn_evt_data);
483         GKI_freebuf(nfa_rw_cb.p_pending_msg);
484         nfa_rw_cb.p_pending_msg = NULL;
485       }
486       /* For all other APIs called during auto-presence check, perform the
487          command now (if tag is still present) */
488       else if (status == NFC_STATUS_OK) {
489         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
490             "Performing deferred operation after presence check...");
491         p_pending_msg = (NFC_HDR*)nfa_rw_cb.p_pending_msg;
492         nfa_rw_cb.p_pending_msg = NULL;
493         nfa_rw_handle_event(p_pending_msg);
494         GKI_freebuf(p_pending_msg);
495       } else {
496         /* Tag no longer present. Free command for pending API command */
497         GKI_freebuf(nfa_rw_cb.p_pending_msg);
498         nfa_rw_cb.p_pending_msg = NULL;
499       }
500     }
501 
502     /* Auto-presence check failed. Deactivate */
503     if (status != NFC_STATUS_OK) {
504       DLOG_IF(INFO, nfc_debug_enabled)
505           << StringPrintf("Auto presence check failed. Deactivating...");
506       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
507     }
508   }
509   /* Handle presence check due to NFA_RwPresenceCheck API call */
510   else {
511     /* Notify app of presence check status */
512     tNFA_CONN_EVT_DATA nfa_conn_evt_data;
513     nfa_conn_evt_data.status = status;
514     nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, &nfa_conn_evt_data);
515 
516     /* If in normal mode (not-exclusive RF mode) then deactivate the link if
517      * presence check failed */
518     if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
519         (nfa_conn_evt_data.status != NFC_STATUS_OK)) {
520       DLOG_IF(INFO, nfc_debug_enabled)
521           << StringPrintf("Presence check failed. Deactivating...");
522       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
523     }
524   }
525 }
526 
527 /*******************************************************************************
528 **
529 ** Function         nfa_rw_handle_t1t_evt
530 **
531 ** Description      Handler for Type-1 tag reader/writer events
532 **
533 ** Returns          Nothing
534 **
535 *******************************************************************************/
nfa_rw_handle_t1t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)536 static void nfa_rw_handle_t1t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
537   tNFA_CONN_EVT_DATA conn_evt_data;
538   tNFA_TAG_PARAMS tag_params;
539   uint8_t* p_rid_rsp;
540   tNFA_STATUS activation_status;
541 
542   conn_evt_data.status = p_rw_data->data.status;
543   switch (event) {
544     case RW_T1T_RID_EVT:
545       if (p_rw_data->data.p_data != NULL) {
546         /* Assume the data is just the response byte sequence */
547         p_rid_rsp = (uint8_t*)(p_rw_data->data.p_data + 1) +
548                     p_rw_data->data.p_data->offset;
549         /* Fetch HR from RID response message */
550         STREAM_TO_ARRAY(tag_params.t1t.hr, p_rid_rsp, T1T_HR_LEN);
551         /* Fetch UID0-3 from RID response message */
552         STREAM_TO_ARRAY(tag_params.t1t.uid, p_rid_rsp, T1T_CMD_UID_LEN);
553         GKI_freebuf(p_rw_data->data.p_data);
554         p_rw_data->data.p_data = NULL;
555       }
556 
557       /* Command complete - perform cleanup, notify the app */
558       nfa_rw_command_complete();
559 
560       if (p_rw_data->status == NFC_STATUS_TIMEOUT) {
561         activation_status = NFA_STATUS_TIMEOUT;
562       } else {
563         activation_status = NFA_STATUS_OK;
564       }
565 
566       nfa_dm_notify_activation_status(activation_status, &tag_params);
567       break;
568 
569     case RW_T1T_RALL_CPLT_EVT:
570     case RW_T1T_READ_CPLT_EVT:
571     case RW_T1T_RSEG_CPLT_EVT:
572     case RW_T1T_READ8_CPLT_EVT:
573       nfa_rw_send_data_to_upper(p_rw_data);
574 
575       /* Command complete - perform cleanup, notify the app */
576       nfa_rw_command_complete();
577       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
578       break;
579 
580     case RW_T1T_WRITE_E_CPLT_EVT:
581     case RW_T1T_WRITE_NE_CPLT_EVT:
582     case RW_T1T_WRITE_E8_CPLT_EVT:
583     case RW_T1T_WRITE_NE8_CPLT_EVT:
584       nfa_rw_send_data_to_upper(p_rw_data);
585 
586       /* Command complete - perform cleanup, notify the app */
587       nfa_rw_command_complete();
588       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
589       break;
590 
591     case RW_T1T_TLV_DETECT_EVT:
592       nfa_rw_handle_tlv_detect(p_rw_data);
593       break;
594 
595     case RW_T1T_NDEF_DETECT_EVT:
596       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
597 
598       if ((p_rw_data->status != NFC_STATUS_OK) &&
599           (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) &&
600           (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATABLE) &&
601           (!(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATED)) &&
602           (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_SUPPORTED)) {
603         /* Tag is in Initialized state, Format the tag first and then Write NDEF
604          */
605         if (RW_T1tFormatNDef() == NFC_STATUS_OK) break;
606       }
607 
608       nfa_rw_handle_ndef_detect(p_rw_data);
609 
610       break;
611 
612     case RW_T1T_NDEF_READ_EVT:
613       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
614       if (p_rw_data->status == NFC_STATUS_OK) {
615         /* Process the ndef record */
616         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
617                                    nfa_rw_cb.ndef_cur_size);
618       } else {
619         /* Notify app of failure */
620         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
621           /* If current operation is READ_NDEF, then notify ndef handlers of
622            * failure */
623           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
624         }
625       }
626 
627       /* Command complete - perform cleanup, notify the app */
628       nfa_rw_command_complete();
629       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
630 
631       /* Free ndef buffer */
632       nfa_rw_free_ndef_rx_buf();
633       break;
634 
635     case RW_T1T_NDEF_WRITE_EVT:
636       if (p_rw_data->data.status != NFA_STATUS_OK)
637         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
638       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
639 
640       /* Command complete - perform cleanup, notify the app */
641       nfa_rw_command_complete();
642 
643       /* Notify app */
644       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
645                                  ? NFA_STATUS_OK
646                                  : NFA_STATUS_FAILED;
647       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
648         /* Update local cursize of ndef message */
649         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
650       }
651 
652       /* Notify app of ndef write complete status */
653       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
654       break;
655 
656     case RW_T1T_SET_TAG_RO_EVT:
657       /* Command complete - perform cleanup, notify the app */
658       nfa_rw_command_complete();
659       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
660       break;
661 
662     case RW_T1T_RAW_FRAME_EVT:
663       nfa_rw_send_data_to_upper(p_rw_data);
664       /* Command complete - perform cleanup */
665       nfa_rw_command_complete();
666       break;
667 
668     case RW_T1T_PRESENCE_CHECK_EVT: /* Presence check completed */
669       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
670       break;
671 
672     case RW_T1T_FORMAT_CPLT_EVT:
673 
674       if (p_rw_data->data.status == NFA_STATUS_OK)
675         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
676 
677       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
678         /* if format operation was done as part of ndef-write operation, now
679          * start NDEF Write */
680         if ((p_rw_data->data.status != NFA_STATUS_OK) ||
681             ((conn_evt_data.status = RW_T1tDetectNDef()) != NFC_STATUS_OK)) {
682           /* Command complete - perform cleanup, notify app */
683           nfa_rw_command_complete();
684           nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
685 
686           /* if format operation failed or ndef detection did not start, then
687            * notify app of ndef-write operation failure */
688           conn_evt_data.status = NFA_STATUS_FAILED;
689           nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
690         }
691       } else {
692         /* Command complete - perform cleanup, notify the app */
693         nfa_rw_command_complete();
694         nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
695       }
696       break;
697 
698     case RW_T1T_INTF_ERROR_EVT:
699       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
700       break;
701   }
702 }
703 
704 /*******************************************************************************
705 **
706 ** Function         nfa_rw_handle_t2t_evt
707 **
708 ** Description      Handler for Type-2 tag reader/writer events
709 **
710 ** Returns          Nothing
711 **
712 *******************************************************************************/
nfa_rw_handle_t2t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)713 static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
714   tNFA_CONN_EVT_DATA conn_evt_data;
715 
716   conn_evt_data.status = p_rw_data->status;
717 
718   if (p_rw_data->status == NFC_STATUS_REJECTED) {
719     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
720         "; Waking the tag first before handling the "
721         "response!");
722     /* Received NACK. Let DM wakeup the tag first (by putting tag to sleep and
723      * then waking it up) */
724     p_rw_data->status = nfa_dm_disc_sleep_wakeup();
725     if (p_rw_data->status == NFC_STATUS_OK) {
726       nfa_rw_cb.halt_event = event;
727       memcpy(&nfa_rw_cb.rw_data, p_rw_data, sizeof(tRW_DATA));
728       return;
729     }
730   }
731 
732   switch (event) {
733     case RW_T2T_READ_CPLT_EVT: /* Read completed          */
734       nfa_rw_send_data_to_upper(p_rw_data);
735       /* Command complete - perform cleanup, notify the app */
736       nfa_rw_command_complete();
737       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
738       break;
739 
740     case RW_T2T_WRITE_CPLT_EVT: /* Write completed         */
741       /* Command complete - perform cleanup, notify the app */
742       nfa_rw_command_complete();
743       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
744       break;
745 
746     case RW_T2T_SELECT_CPLT_EVT: /* Sector select completed */
747       /* Command complete - perform cleanup, notify the app */
748       nfa_rw_command_complete();
749       nfa_dm_act_conn_cback_notify(NFA_SELECT_CPLT_EVT, &conn_evt_data);
750       break;
751 
752     case RW_T2T_NDEF_DETECT_EVT: /* NDEF detection complete */
753       if ((p_rw_data->status == NFC_STATUS_OK) ||
754           ((p_rw_data->status == NFC_STATUS_FAILED) &&
755            ((p_rw_data->ndef.flags == NFA_RW_NDEF_FL_UNKNOWN) ||
756             (nfa_rw_cb.halt_event == RW_T2T_MAX_EVT))) ||
757           (nfa_rw_cb.skip_dyn_locks == true)) {
758         /* NDEF Detection is complete */
759         nfa_rw_cb.skip_dyn_locks = false;
760         nfa_rw_handle_ndef_detect(p_rw_data);
761       } else {
762         /* Try to detect NDEF again, this time without reading dynamic lock
763          * bytes */
764         nfa_rw_cb.skip_dyn_locks = true;
765         nfa_rw_detect_ndef();
766       }
767       break;
768 
769     case RW_T2T_TLV_DETECT_EVT: /* Lock control/Mem/Prop tlv detection complete
770                                    */
771       nfa_rw_handle_tlv_detect(p_rw_data);
772       break;
773 
774     case RW_T2T_NDEF_READ_EVT: /* NDEF read completed     */
775       if (p_rw_data->status == NFC_STATUS_OK) {
776         /* Process the ndef record */
777         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
778                                    nfa_rw_cb.ndef_cur_size);
779       } else {
780         /* Notify app of failure */
781         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
782           /* If current operation is READ_NDEF, then notify ndef handlers of
783            * failure */
784           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
785         }
786       }
787 
788       /* Notify app of read status */
789       conn_evt_data.status = p_rw_data->status;
790       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
791       /* Free ndef buffer */
792       nfa_rw_free_ndef_rx_buf();
793 
794       /* Command complete - perform cleanup */
795       nfa_rw_command_complete();
796       break;
797 
798     case RW_T2T_NDEF_WRITE_EVT: /* NDEF write complete     */
799 
800       /* Command complete - perform cleanup, notify the app */
801       nfa_rw_command_complete();
802 
803       /* Notify app */
804       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
805                                  ? NFA_STATUS_OK
806                                  : NFA_STATUS_FAILED;
807       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
808         /* Update local cursize of ndef message */
809         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
810       }
811 
812       /* Notify app of ndef write complete status */
813       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
814 
815       break;
816 
817     case RW_T2T_SET_TAG_RO_EVT:
818       /* Command complete - perform cleanup, notify the app */
819       nfa_rw_command_complete();
820       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
821       break;
822 
823     case RW_T2T_RAW_FRAME_EVT:
824       nfa_rw_send_data_to_upper(p_rw_data);
825       /* Command complete - perform cleanup */
826       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
827         nfa_rw_command_complete();
828       }
829       break;
830 
831     case RW_T2T_PRESENCE_CHECK_EVT: /* Presence check completed */
832       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
833       break;
834 
835     case RW_T2T_FORMAT_CPLT_EVT:
836       if (p_rw_data->data.status == NFA_STATUS_OK)
837         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
838 
839       /* Command complete - perform cleanup, notify the app */
840       nfa_rw_command_complete();
841       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
842       break;
843 
844     case RW_T2T_INTF_ERROR_EVT:
845       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
846       break;
847   }
848 }
849 
850 /*******************************************************************************
851 **
852 ** Function         nfa_rw_handle_t3t_evt
853 **
854 ** Description      Handler for Type-3 tag reader/writer events
855 **
856 ** Returns          Nothing
857 **
858 *******************************************************************************/
nfa_rw_handle_t3t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)859 static void nfa_rw_handle_t3t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
860   tNFA_CONN_EVT_DATA conn_evt_data;
861   tNFA_TAG_PARAMS tag_params;
862 
863   switch (event) {
864     case RW_T3T_NDEF_DETECT_EVT: /* NDEF detection complete */
865       nfa_rw_handle_ndef_detect(p_rw_data);
866       break;
867 
868     case RW_T3T_UPDATE_CPLT_EVT: /* Write completed */
869       /* Command complete - perform cleanup, notify the app */
870       nfa_rw_command_complete();
871 
872       /* Notify app */
873       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
874                                  ? NFA_STATUS_OK
875                                  : NFA_STATUS_FAILED;
876       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
877         /* Update local cursize of ndef message */
878         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
879       }
880 
881       /* Notify app of ndef write complete status */
882       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
883 
884       break;
885 
886     case RW_T3T_CHECK_CPLT_EVT: /* Read completed */
887       if (p_rw_data->status == NFC_STATUS_OK) {
888         /* Process the ndef record */
889         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
890                                    nfa_rw_cb.ndef_cur_size);
891       } else {
892         /* Notify app of failure */
893         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
894           /* If current operation is READ_NDEF, then notify ndef handlers of
895            * failure */
896           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
897         }
898       }
899 
900       /* Free ndef buffer */
901       nfa_rw_free_ndef_rx_buf();
902 
903       /* Command complete - perform cleanup, notify the app */
904       nfa_rw_command_complete();
905       conn_evt_data.status = p_rw_data->status;
906       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
907       break;
908 
909     case RW_T3T_CHECK_EVT: /* Segment of data received from type 3 tag */
910       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
911         nfa_rw_store_ndef_rx_buf(p_rw_data);
912       } else {
913         nfa_rw_send_data_to_upper(p_rw_data);
914       }
915       break;
916 
917     case RW_T3T_RAW_FRAME_EVT: /* SendRawFrame response */
918       nfa_rw_send_data_to_upper(p_rw_data);
919 
920       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
921         /* Command complete - perform cleanup */
922         nfa_rw_command_complete();
923       }
924       break;
925 
926     case RW_T3T_PRESENCE_CHECK_EVT: /* Presence check completed */
927       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
928       break;
929 
930     case RW_T3T_GET_SYSTEM_CODES_EVT: /* Presence check completed */
931       /* Command complete - perform cleanup */
932       nfa_rw_command_complete();
933 
934       /* System codes retrieved - notify app of ACTIVATION */
935       if (p_rw_data->status == NFC_STATUS_OK) {
936         tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes;
937         tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes;
938       } else {
939         tag_params.t3t.num_system_codes = 0;
940         tag_params.t3t.p_system_codes = NULL;
941       }
942 
943       nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
944       break;
945 
946     case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */
947       /* Command complete - perform cleanup, notify the app */
948       nfa_rw_command_complete();
949 
950       /* Notify app */
951       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
952                                  ? NFA_STATUS_OK
953                                  : NFA_STATUS_FAILED;
954 
955       /* Notify app of ndef write complete status */
956       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
957       break;
958 
959     case RW_T3T_INTF_ERROR_EVT:
960       conn_evt_data.status = p_rw_data->status;
961       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
962       break;
963 
964     case RW_T3T_SET_READ_ONLY_CPLT_EVT:
965       /* Command complete - perform cleanup, notify the app */
966       nfa_rw_command_complete();
967 
968       conn_evt_data.status = p_rw_data->status;
969       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
970       break;
971 
972     default:
973       DLOG_IF(INFO, nfc_debug_enabled)
974           << StringPrintf("; Unhandled RW event 0x%X", event);
975       break;
976   }
977 }
978 
979 /*******************************************************************************
980 **
981 ** Function         nfa_rw_handle_t4t_evt
982 **
983 ** Description      Handler for Type-4 tag reader/writer events
984 **
985 ** Returns          Nothing
986 **
987 *******************************************************************************/
nfa_rw_handle_t4t_evt(tRW_EVENT event,tRW_DATA * p_rw_data)988 static void nfa_rw_handle_t4t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
989   tNFA_CONN_EVT_DATA conn_evt_data;
990 
991   switch (event) {
992     case RW_T4T_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
993       nfa_rw_handle_ndef_detect(p_rw_data);
994       break;
995 
996     case RW_T4T_NDEF_FORMAT_CPLT_EVT:
997       /* Command complete - perform cleanup, notify the app */
998       nfa_rw_command_complete();
999       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1000       nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
1001       nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
1002       conn_evt_data.status = (p_rw_data->status == NFC_STATUS_OK)
1003                                  ? NFA_STATUS_OK
1004                                  : NFA_STATUS_FAILED;
1005 
1006       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
1007       break;
1008 
1009     case RW_T4T_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
1010       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1011         nfa_rw_store_ndef_rx_buf(p_rw_data);
1012       } else {
1013         nfa_rw_send_data_to_upper(p_rw_data);
1014       }
1015       break;
1016 
1017     case RW_T4T_NDEF_READ_CPLT_EVT: /* Read operation completed           */
1018       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1019         nfa_rw_store_ndef_rx_buf(p_rw_data);
1020 
1021         /* Process the ndef record */
1022         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
1023                                    nfa_rw_cb.ndef_cur_size);
1024 
1025         /* Free ndef buffer */
1026         nfa_rw_free_ndef_rx_buf();
1027       } else {
1028         nfa_rw_send_data_to_upper(p_rw_data);
1029       }
1030 
1031       /* Command complete - perform cleanup, notify the app */
1032       nfa_rw_command_complete();
1033       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1034       conn_evt_data.status = NFC_STATUS_OK;
1035       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1036       break;
1037 
1038     case RW_T4T_NDEF_READ_FAIL_EVT: /* Read operation failed              */
1039       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1040         /* If current operation is READ_NDEF, then notify ndef handlers of
1041          * failure */
1042         nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
1043 
1044         /* Free ndef buffer */
1045         nfa_rw_free_ndef_rx_buf();
1046       }
1047 
1048       /* Command complete - perform cleanup, notify the app */
1049       nfa_rw_command_complete();
1050       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1051       conn_evt_data.status = NFA_STATUS_FAILED;
1052       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1053       break;
1054 
1055     case RW_T4T_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
1056     case RW_T4T_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
1057 
1058       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
1059         /* Update local cursize of ndef message */
1060         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
1061       }
1062 
1063       /* Notify app */
1064       if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT)
1065         conn_evt_data.status = NFA_STATUS_OK;
1066       else
1067         conn_evt_data.status = NFA_STATUS_FAILED;
1068 
1069       /* Command complete - perform cleanup, notify the app */
1070       nfa_rw_command_complete();
1071       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1072       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1073       break;
1074 
1075     case RW_T4T_RAW_FRAME_EVT: /* Raw Frame data event         */
1076       nfa_rw_send_data_to_upper(p_rw_data);
1077 
1078       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
1079         /* Command complete - perform cleanup */
1080         nfa_rw_command_complete();
1081         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1082       }
1083       break;
1084 
1085     case RW_T4T_SET_TO_RO_EVT: /* Tag is set as read only          */
1086       conn_evt_data.status = p_rw_data->status;
1087       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
1088 
1089       nfa_rw_command_complete();
1090       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1091       break;
1092 
1093     case RW_T4T_INTF_ERROR_EVT: /* RF Interface error event         */
1094       conn_evt_data.status = p_rw_data->status;
1095       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
1096 
1097       nfa_rw_command_complete();
1098       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
1099       break;
1100 
1101     case RW_T4T_PRESENCE_CHECK_EVT: /* Presence check completed */
1102       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
1103       break;
1104 
1105     default:
1106       DLOG_IF(INFO, nfc_debug_enabled)
1107           << StringPrintf("; Unhandled RW event 0x%X", event);
1108       break;
1109   }
1110 }
1111 
1112 /*******************************************************************************
1113 **
1114 ** Function         nfa_rw_handle_i93_evt
1115 **
1116 ** Description      Handler for ISO 15693 tag reader/writer events
1117 **
1118 ** Returns          Nothing
1119 **
1120 *******************************************************************************/
nfa_rw_handle_i93_evt(tRW_EVENT event,tRW_DATA * p_rw_data)1121 static void nfa_rw_handle_i93_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
1122   tNFA_CONN_EVT_DATA conn_evt_data;
1123   tNFA_TAG_PARAMS i93_params;
1124 
1125   switch (event) {
1126     case RW_I93_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
1127       nfa_rw_handle_ndef_detect(p_rw_data);
1128       break;
1129 
1130     case RW_I93_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
1131       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1132         nfa_rw_store_ndef_rx_buf(p_rw_data);
1133       } else {
1134         nfa_rw_send_data_to_upper(p_rw_data);
1135       }
1136       break;
1137 
1138     case RW_I93_NDEF_READ_CPLT_EVT: /* Read operation completed           */
1139       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1140         nfa_rw_store_ndef_rx_buf(p_rw_data);
1141 
1142         /* Process the ndef record */
1143         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
1144                                    nfa_rw_cb.ndef_cur_size);
1145 
1146         /* Free ndef buffer */
1147         nfa_rw_free_ndef_rx_buf();
1148       } else {
1149         nfa_rw_send_data_to_upper(p_rw_data);
1150       }
1151 
1152       /* Command complete - perform cleanup, notify app */
1153       nfa_rw_command_complete();
1154       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1155       conn_evt_data.status = NFC_STATUS_OK;
1156       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1157       break;
1158 
1159     case RW_I93_NDEF_READ_FAIL_EVT: /* Read operation failed              */
1160       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
1161         /* If current operation is READ_NDEF, then notify ndef handlers of
1162          * failure */
1163         nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
1164 
1165         /* Free ndef buffer */
1166         nfa_rw_free_ndef_rx_buf();
1167       }
1168 
1169       /* Command complete - perform cleanup, notify app */
1170       nfa_rw_command_complete();
1171       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1172       conn_evt_data.status = NFA_STATUS_FAILED;
1173       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1174       break;
1175 
1176     case RW_I93_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
1177     case RW_I93_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
1178 
1179       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
1180         /* Update local cursize of ndef message */
1181         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
1182       }
1183 
1184       /* Command complete - perform cleanup, notify app */
1185       nfa_rw_command_complete();
1186       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1187 
1188       if (event == RW_I93_NDEF_UPDATE_CPLT_EVT)
1189         conn_evt_data.status = NFA_STATUS_OK;
1190       else
1191         conn_evt_data.status = NFA_STATUS_FAILED;
1192 
1193       /* Notify app of ndef write complete status */
1194       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1195       break;
1196 
1197     case RW_I93_RAW_FRAME_EVT: /* Raw Frame data event         */
1198       nfa_rw_send_data_to_upper(p_rw_data);
1199       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
1200         /* Command complete - perform cleanup */
1201         nfa_rw_command_complete();
1202       }
1203       break;
1204 
1205     case RW_I93_INTF_ERROR_EVT: /* RF Interface error event         */
1206       /* Command complete - perform cleanup, notify app */
1207       nfa_rw_command_complete();
1208 
1209       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
1210         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1211 
1212         memset(&i93_params, 0x00, sizeof(tNFA_TAG_PARAMS));
1213         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1214 
1215         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
1216       } else {
1217         conn_evt_data.status = p_rw_data->status;
1218         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
1219       }
1220 
1221       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1222       break;
1223 
1224     case RW_I93_PRESENCE_CHECK_EVT: /* Presence check completed */
1225       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
1226       break;
1227 
1228     case RW_I93_FORMAT_CPLT_EVT: /* Format procedure complete          */
1229       if (p_rw_data->data.status == NFA_STATUS_OK)
1230         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1231 
1232       /* Command complete - perform cleanup, notify app */
1233       nfa_rw_command_complete();
1234       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1235       conn_evt_data.status = p_rw_data->status;
1236       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
1237       break;
1238 
1239     case RW_I93_SET_TAG_RO_EVT: /* Set read-only procedure complete   */
1240       nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
1241 
1242       /* Command complete - perform cleanup, notify app */
1243       nfa_rw_command_complete();
1244       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1245       conn_evt_data.status = p_rw_data->status;
1246       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
1247       break;
1248 
1249     case RW_I93_INVENTORY_EVT: /* Response of Inventory              */
1250 
1251       /* Command complete - perform cleanup, notify app */
1252       nfa_rw_command_complete();
1253 
1254       conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status;
1255       conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
1256 
1257       conn_evt_data.i93_cmd_cplt.params.inventory.dsfid =
1258           p_rw_data->i93_inventory.dsfid;
1259       memcpy(conn_evt_data.i93_cmd_cplt.params.inventory.uid,
1260              p_rw_data->i93_inventory.uid, I93_UID_BYTE_LEN);
1261 
1262       nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1263 
1264       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1265       break;
1266 
1267     case RW_I93_DATA_EVT: /* Response of Read, Get Multi Security */
1268 
1269       /* Command complete - perform cleanup, notify app */
1270       nfa_rw_command_complete();
1271 
1272       conn_evt_data.data.p_data = (uint8_t*)(p_rw_data->i93_data.p_data + 1) +
1273                                   p_rw_data->i93_data.p_data->offset;
1274 
1275       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
1276         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1277 
1278         i93_params.i93.info_flags =
1279             (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_AFI);
1280         i93_params.i93.afi =
1281             *(conn_evt_data.data.p_data +
1282               nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
1283         i93_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
1284         i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
1285         i93_params.i93.num_block = nfa_rw_cb.i93_num_block;
1286         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1287 
1288         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
1289       } else {
1290         conn_evt_data.data.len = p_rw_data->i93_data.p_data->len;
1291 
1292         nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
1293       }
1294 
1295       GKI_freebuf(p_rw_data->i93_data.p_data);
1296       p_rw_data->i93_data.p_data = NULL;
1297 
1298       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1299       break;
1300 
1301     case RW_I93_SYS_INFO_EVT: /* Response of System Information     */
1302 
1303       /* Command complete - perform cleanup, notify app */
1304       nfa_rw_command_complete();
1305 
1306       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
1307         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1308 
1309         nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1310         nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
1311 
1312         i93_params.i93.info_flags = p_rw_data->i93_sys_info.info_flags;
1313         i93_params.i93.dsfid = p_rw_data->i93_sys_info.dsfid;
1314         i93_params.i93.afi = p_rw_data->i93_sys_info.afi;
1315         i93_params.i93.num_block = p_rw_data->i93_sys_info.num_block;
1316         i93_params.i93.block_size = p_rw_data->i93_sys_info.block_size;
1317         i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
1318         memcpy(i93_params.i93.uid, p_rw_data->i93_sys_info.uid,
1319                I93_UID_BYTE_LEN);
1320 
1321         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
1322       } else {
1323         conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_sys_info.status;
1324         conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
1325 
1326         conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags =
1327             p_rw_data->i93_sys_info.info_flags;
1328         memcpy(conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
1329                p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
1330         conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid =
1331             p_rw_data->i93_sys_info.dsfid;
1332         conn_evt_data.i93_cmd_cplt.params.sys_info.afi =
1333             p_rw_data->i93_sys_info.afi;
1334         conn_evt_data.i93_cmd_cplt.params.sys_info.num_block =
1335             p_rw_data->i93_sys_info.num_block;
1336         conn_evt_data.i93_cmd_cplt.params.sys_info.block_size =
1337             p_rw_data->i93_sys_info.block_size;
1338         conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference =
1339             p_rw_data->i93_sys_info.IC_reference;
1340 
1341         /* store tag memory information for writing blocks */
1342         nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1343         nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
1344 
1345         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1346       }
1347 
1348       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1349       break;
1350 
1351     case RW_I93_CMD_CMPL_EVT: /* Command complete                   */
1352       /* Command complete - perform cleanup, notify app */
1353       nfa_rw_command_complete();
1354 
1355       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
1356         /* Reader got error code from tag */
1357 
1358         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1359 
1360         memset(&i93_params, 0x00, sizeof(i93_params));
1361         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1362 
1363         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
1364       } else {
1365         conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_cmd_cmpl.status;
1366         conn_evt_data.i93_cmd_cplt.sent_command =
1367             p_rw_data->i93_cmd_cmpl.command;
1368 
1369         if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
1370           conn_evt_data.i93_cmd_cplt.params.error_code =
1371               p_rw_data->i93_cmd_cmpl.error_code;
1372 
1373         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1374       }
1375 
1376       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1377       break;
1378 
1379     default:
1380       DLOG_IF(INFO, nfc_debug_enabled)
1381           << StringPrintf("; Unhandled RW event 0x%X", event);
1382       break;
1383   }
1384 }
1385 
1386 /*******************************************************************************
1387 **
1388 ** Function         nfa_rw_cback
1389 **
1390 ** Description      Callback for reader/writer event notification
1391 **
1392 ** Returns          Nothing
1393 **
1394 *******************************************************************************/
nfa_rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)1395 static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
1396   DLOG_IF(INFO, nfc_debug_enabled)
1397       << StringPrintf("nfa_rw_cback: event=0x%02x", event);
1398 
1399   /* Call appropriate event handler for tag type */
1400   if (event < RW_T1T_MAX_EVT) {
1401     /* Handle Type-1 tag events */
1402     nfa_rw_handle_t1t_evt(event, p_rw_data);
1403   } else if (event < RW_T2T_MAX_EVT) {
1404     /* Handle Type-2 tag events */
1405     nfa_rw_handle_t2t_evt(event, p_rw_data);
1406   } else if (event < RW_T3T_MAX_EVT) {
1407     /* Handle Type-3 tag events */
1408     nfa_rw_handle_t3t_evt(event, p_rw_data);
1409   } else if (event < RW_T4T_MAX_EVT) {
1410     /* Handle Type-4 tag events */
1411     nfa_rw_handle_t4t_evt(event, p_rw_data);
1412   } else if (event < RW_I93_MAX_EVT) {
1413     /* Handle ISO 15693 tag events */
1414     nfa_rw_handle_i93_evt(event, p_rw_data);
1415   } else {
1416     LOG(ERROR) << StringPrintf("nfa_rw_cback: unhandled event=0x%02x", event);
1417   }
1418 }
1419 
1420 /*******************************************************************************
1421 **
1422 ** Function         nfa_rw_start_ndef_detection
1423 **
1424 ** Description      Start NDEF detection on activated tag
1425 **
1426 ** Returns          Nothing
1427 **
1428 *******************************************************************************/
nfa_rw_start_ndef_detection(void)1429 static tNFC_STATUS nfa_rw_start_ndef_detection(void) {
1430   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1431   tNFC_STATUS status = NFC_STATUS_FAILED;
1432 
1433   if (NFC_PROTOCOL_T1T == protocol) {
1434     /* Type1Tag    - NFC-A */
1435     status = RW_T1tDetectNDef();
1436   } else if (NFC_PROTOCOL_T2T == protocol) {
1437     /* Type2Tag    - NFC-A */
1438     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1439       status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks);
1440     }
1441   } else if (NFC_PROTOCOL_T3T == protocol) {
1442     /* Type3Tag    - NFC-F */
1443     status = RW_T3tDetectNDef();
1444   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
1445     /* ISODEP/4A,4B- NFC-A or NFC-B */
1446     status = RW_T4tDetectNDef();
1447   } else if (NFC_PROTOCOL_T5T == protocol) {
1448     /* ISO 15693 */
1449     status = RW_I93DetectNDef();
1450   }
1451 
1452   return (status);
1453 }
1454 
1455 /*******************************************************************************
1456 **
1457 ** Function         nfa_rw_start_ndef_read
1458 **
1459 ** Description      Start NDEF read on activated tag
1460 **
1461 ** Returns          Nothing
1462 **
1463 *******************************************************************************/
nfa_rw_start_ndef_read(void)1464 static tNFC_STATUS nfa_rw_start_ndef_read(void) {
1465   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1466   tNFC_STATUS status = NFC_STATUS_FAILED;
1467   tNFA_CONN_EVT_DATA conn_evt_data;
1468 
1469   /* Handle zero length NDEF message */
1470   if (nfa_rw_cb.ndef_cur_size == 0) {
1471     DLOG_IF(INFO, nfc_debug_enabled)
1472         << StringPrintf("NDEF message is zero-length");
1473 
1474     /* Send zero-lengh NDEF message to ndef callback */
1475     nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
1476 
1477     /* Command complete - perform cleanup, notify app */
1478     nfa_rw_command_complete();
1479     conn_evt_data.status = NFA_STATUS_OK;
1480     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1481     return NFC_STATUS_OK;
1482   }
1483 
1484   /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if
1485    * needed) */
1486   nfa_rw_free_ndef_rx_buf();
1487   nfa_rw_cb.p_ndef_buf = (uint8_t*)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size);
1488   if (nfa_rw_cb.p_ndef_buf == NULL) {
1489     LOG(ERROR) << StringPrintf(
1490         "Unable to allocate a buffer for reading NDEF (size=%i)",
1491         nfa_rw_cb.ndef_cur_size);
1492 
1493     /* Command complete - perform cleanup, notify app */
1494     nfa_rw_command_complete();
1495     conn_evt_data.status = NFA_STATUS_FAILED;
1496     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1497     return NFC_STATUS_FAILED;
1498   }
1499   nfa_rw_cb.ndef_rd_offset = 0;
1500 
1501   if (NFC_PROTOCOL_T1T == protocol) {
1502     /* Type1Tag    - NFC-A */
1503     status =
1504         RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf, (uint16_t)nfa_rw_cb.ndef_cur_size);
1505   } else if (NFC_PROTOCOL_T2T == protocol) {
1506     /* Type2Tag    - NFC-A */
1507     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1508       status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,
1509                               (uint16_t)nfa_rw_cb.ndef_cur_size);
1510     }
1511   } else if (NFC_PROTOCOL_T3T == protocol) {
1512     /* Type3Tag    - NFC-F */
1513     status = RW_T3tCheckNDef();
1514   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
1515     /* ISODEP/4A,4B- NFC-A or NFC-B */
1516     status = RW_T4tReadNDef();
1517   } else if (NFC_PROTOCOL_T5T == protocol) {
1518     /* ISO 15693 */
1519     status = RW_I93ReadNDef();
1520   }
1521 
1522   return (status);
1523 }
1524 
1525 /*******************************************************************************
1526 **
1527 ** Function         nfa_rw_detect_ndef
1528 **
1529 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1530 **
1531 ** Returns          TRUE (message buffer to be freed by caller)
1532 **
1533 *******************************************************************************/
nfa_rw_detect_ndef()1534 static bool nfa_rw_detect_ndef() {
1535   tNFA_CONN_EVT_DATA conn_evt_data;
1536   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1537 
1538   conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection();
1539   if (conn_evt_data.ndef_detect.status != NFC_STATUS_OK) {
1540     /* Command complete - perform cleanup, notify app */
1541     nfa_rw_command_complete();
1542     conn_evt_data.ndef_detect.cur_size = 0;
1543     conn_evt_data.ndef_detect.max_size = 0;
1544     conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
1545     nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
1546   }
1547 
1548   return true;
1549 }
1550 
1551 /*******************************************************************************
1552 **
1553 ** Function         nfa_rw_start_ndef_write
1554 **
1555 ** Description      Start NDEF write on activated tag
1556 **
1557 ** Returns          Nothing
1558 **
1559 *******************************************************************************/
nfa_rw_start_ndef_write(void)1560 static tNFC_STATUS nfa_rw_start_ndef_write(void) {
1561   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1562   tNFC_STATUS status = NFC_STATUS_FAILED;
1563 
1564   if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY) {
1565     /* error: ndef tag is read-only */
1566     status = NFC_STATUS_FAILED;
1567     LOG(ERROR) << StringPrintf("Unable to write NDEF. Tag is read-only");
1568   } else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len) {
1569     /* error: ndef tag size is too small */
1570     status = NFC_STATUS_BUFFER_FULL;
1571     LOG(ERROR) << StringPrintf(
1572         "Unable to write NDEF. Tag maxsize=%i, request write size=%i",
1573         nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len);
1574   } else {
1575     if (NFC_PROTOCOL_T1T == protocol) {
1576       /* Type1Tag    - NFC-A */
1577       status = RW_T1tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
1578                                nfa_rw_cb.p_ndef_wr_buf);
1579     } else if (NFC_PROTOCOL_T2T == protocol) {
1580       /* Type2Tag    - NFC-A */
1581       if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1582         status = RW_T2tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
1583                                  nfa_rw_cb.p_ndef_wr_buf);
1584       }
1585     } else if (NFC_PROTOCOL_T3T == protocol) {
1586       /* Type3Tag    - NFC-F */
1587       status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1588     } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
1589       /* ISODEP/4A,4B- NFC-A or NFC-B */
1590       status = RW_T4tUpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
1591                                 nfa_rw_cb.p_ndef_wr_buf);
1592     } else if (NFC_PROTOCOL_T5T == protocol) {
1593       /* ISO 15693 */
1594       status = RW_I93UpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
1595                                 nfa_rw_cb.p_ndef_wr_buf);
1596     }
1597   }
1598 
1599   return (status);
1600 }
1601 
1602 /*******************************************************************************
1603 **
1604 ** Function         nfa_rw_read_ndef
1605 **
1606 ** Description      Handler for NFA_RW_API_READ_NDEF_EVT
1607 **
1608 ** Returns          TRUE (message buffer to be freed by caller)
1609 **
1610 *******************************************************************************/
nfa_rw_read_ndef()1611 static bool nfa_rw_read_ndef() {
1612   tNFA_STATUS status = NFA_STATUS_OK;
1613   tNFA_CONN_EVT_DATA conn_evt_data;
1614 
1615   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1616 
1617   /* Check if ndef detection has been performed yet */
1618   if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
1619     /* Perform ndef detection first */
1620     status = nfa_rw_start_ndef_detection();
1621   } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
1622     /* Tag is not NDEF */
1623     status = NFA_STATUS_FAILED;
1624   } else {
1625     /* Perform the NDEF read operation */
1626     status = nfa_rw_start_ndef_read();
1627   }
1628 
1629   /* Handle failure */
1630   if (status != NFA_STATUS_OK) {
1631     /* Command complete - perform cleanup, notify app */
1632     nfa_rw_command_complete();
1633     conn_evt_data.status = status;
1634     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1635   }
1636 
1637   return true;
1638 }
1639 
1640 /*******************************************************************************
1641 **
1642 ** Function         nfa_rw_write_ndef
1643 **
1644 ** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
1645 **
1646 ** Returns          TRUE (message buffer to be freed by caller)
1647 **
1648 *******************************************************************************/
nfa_rw_write_ndef(tNFA_RW_MSG * p_data)1649 static bool nfa_rw_write_ndef(tNFA_RW_MSG* p_data) {
1650   tNDEF_STATUS ndef_status;
1651   tNFA_STATUS write_status = NFA_STATUS_OK;
1652   tNFA_CONN_EVT_DATA conn_evt_data;
1653   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1654 
1655   /* Validate NDEF message */
1656   ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data,
1657                                  p_data->op_req.params.write_ndef.len, false);
1658   if (ndef_status != NDEF_OK) {
1659     LOG(ERROR) << StringPrintf(
1660         "Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status);
1661 
1662     /* Command complete - perform cleanup, notify app */
1663     nfa_rw_command_complete();
1664     conn_evt_data.status = NFA_STATUS_FAILED;
1665     nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1666     return true;
1667   }
1668 
1669   /* Store pointer to source NDEF */
1670   nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
1671   nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
1672 
1673   /* Check if ndef detection has been performed yet */
1674   if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
1675     /* Perform ndef detection first */
1676     write_status = nfa_rw_start_ndef_detection();
1677   } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
1678     if (nfa_rw_cb.protocol == NFC_PROTOCOL_T1T) {
1679       /* For Type 1 tag, NDEF can be written on Initialized tag
1680       *  Perform ndef detection first to check if tag is in Initialized state to
1681       * Write NDEF */
1682       write_status = nfa_rw_start_ndef_detection();
1683     } else {
1684       /* Tag is not NDEF */
1685       write_status = NFA_STATUS_FAILED;
1686     }
1687   } else {
1688     /* Perform the NDEF read operation */
1689     write_status = nfa_rw_start_ndef_write();
1690   }
1691 
1692   /* Handle failure */
1693   if (write_status != NFA_STATUS_OK) {
1694     /* Command complete - perform cleanup, notify app */
1695     nfa_rw_command_complete();
1696     conn_evt_data.status = write_status;
1697     nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1698   }
1699 
1700   return true;
1701 }
1702 
1703 /*******************************************************************************
1704 **
1705 ** Function         nfa_rw_presence_check
1706 **
1707 ** Description      Handler for NFA_RW_API_PRESENCE_CHECK
1708 **
1709 ** Returns          Nothing
1710 **
1711 *******************************************************************************/
nfa_rw_presence_check(tNFA_RW_MSG * p_data)1712 void nfa_rw_presence_check(tNFA_RW_MSG* p_data) {
1713   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1714   uint8_t sel_res = nfa_rw_cb.pa_sel_res;
1715   tNFC_STATUS status = NFC_STATUS_FAILED;
1716   bool unsupported = false;
1717   uint8_t option = NFA_RW_OPTION_INVALID;
1718   tNFA_RW_PRES_CHK_OPTION op_param = NFA_RW_PRES_CHK_DEFAULT;
1719 
1720   if (NFC_PROTOCOL_T1T == protocol) {
1721     /* Type1Tag    - NFC-A */
1722     status = RW_T1tPresenceCheck();
1723   } else if (NFC_PROTOCOL_T2T == protocol) {
1724     /* If T2T NFC-Forum, then let RW handle presence check */
1725     if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1726       /* Type 2 tag have not sent NACK after activation */
1727       status = RW_T2tPresenceCheck();
1728     } else {
1729       /* Will fall back to deactivate/reactivate */
1730       unsupported = true;
1731     }
1732   } else if (NFC_PROTOCOL_T3T == protocol) {
1733     /* Type3Tag    - NFC-F */
1734     status = RW_T3tPresenceCheck();
1735   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
1736     /* ISODEP/4A,4B- NFC-A or NFC-B */
1737     if (p_data) {
1738       op_param = p_data->op_req.params.option;
1739     }
1740 
1741     switch (op_param) {
1742       case NFA_RW_PRES_CHK_I_BLOCK:
1743         option = RW_T4T_CHK_EMPTY_I_BLOCK;
1744         break;
1745 
1746       case NFA_RW_PRES_CHK_ISO_DEP_NAK:
1747         if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
1748           option = RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK;
1749         }
1750         break;
1751       default:
1752         /* empty I block */
1753         option = RW_T4T_CHK_EMPTY_I_BLOCK;
1754     }
1755 
1756     if (option != NFA_RW_OPTION_INVALID) {
1757       /* use the presence check with the chosen option */
1758       status = RW_T4tPresenceCheck(option);
1759     } else {
1760       /* use sleep/wake for presence check */
1761       unsupported = true;
1762     }
1763   } else if (NFC_PROTOCOL_T5T == protocol) {
1764     /* T5T/ISO 15693 */
1765     status = RW_I93PresenceCheck();
1766   } else {
1767     /* Protocol unsupported by RW module... */
1768     unsupported = true;
1769   }
1770 
1771   if (unsupported) {
1772     if (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) {
1773       /* start Kovio presence check (deactivate and wait for activation) */
1774       status = nfa_dm_disc_start_kovio_presence_check();
1775     } else {
1776       /* Let DM perform presence check (by putting tag to sleep and then waking
1777        * it up) */
1778       status = nfa_dm_disc_sleep_wakeup();
1779     }
1780   }
1781 
1782   /* Handle presence check failure */
1783   if (status != NFC_STATUS_OK)
1784     nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
1785   else if (!unsupported) {
1786     nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT,
1787                         p_nfa_dm_cfg->presence_check_timeout);
1788   }
1789 }
1790 
1791 /*******************************************************************************
1792 **
1793 ** Function         nfa_rw_presence_check_tick
1794 **
1795 ** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
1796 **                  Initiate presence check
1797 **
1798 ** Returns          TRUE (caller frees message buffer)
1799 **
1800 *******************************************************************************/
nfa_rw_presence_check_tick(tNFA_RW_MSG * p_data)1801 bool nfa_rw_presence_check_tick(__attribute__((unused)) tNFA_RW_MSG* p_data) {
1802   /* Store the current operation */
1803   nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
1804   nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
1805   DLOG_IF(INFO, nfc_debug_enabled)
1806       << StringPrintf("Auto-presence check starting...");
1807 
1808   /* Perform presence check */
1809   nfa_rw_presence_check(NULL);
1810 
1811   return true;
1812 }
1813 
1814 /*******************************************************************************
1815 **
1816 ** Function         nfa_rw_presence_check_timeout
1817 **
1818 ** Description      presence check timeout: report presence check failure
1819 **
1820 ** Returns          TRUE (caller frees message buffer)
1821 **
1822 *******************************************************************************/
nfa_rw_presence_check_timeout(tNFA_RW_MSG * p_data)1823 bool nfa_rw_presence_check_timeout(__attribute__((unused))
1824                                    tNFA_RW_MSG* p_data) {
1825   nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
1826   return true;
1827 }
1828 
1829 /*******************************************************************************
1830 **
1831 ** Function         nfa_rw_format_tag
1832 **
1833 ** Description      Handler for NFA_RW_API_FORMAT_TAG
1834 **
1835 ** Returns          Nothing
1836 **
1837 *******************************************************************************/
nfa_rw_format_tag()1838 static void nfa_rw_format_tag() {
1839   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1840   tNFC_STATUS status = NFC_STATUS_FAILED;
1841 
1842   if (protocol == NFC_PROTOCOL_T1T) {
1843     status = RW_T1tFormatNDef();
1844   } else if ((protocol == NFC_PROTOCOL_T2T) &&
1845              (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
1846     status = RW_T2tFormatNDef();
1847   } else if (protocol == NFC_PROTOCOL_T3T) {
1848     status = RW_T3tFormatNDef();
1849   } else if (protocol == NFC_PROTOCOL_T5T) {
1850     status = RW_I93FormatNDef();
1851   } else if (protocol == NFC_PROTOCOL_ISO_DEP) {
1852     status = RW_T4tFormatNDef();
1853   }
1854 
1855   /* If unable to format NDEF, notify the app */
1856   if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_FORMAT_CPLT_EVT);
1857 }
1858 
1859 /*******************************************************************************
1860 **
1861 ** Function         nfa_rw_detect_tlv
1862 **
1863 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1864 **
1865 ** Returns          TRUE (message buffer to be freed by caller)
1866 **
1867 *******************************************************************************/
nfa_rw_detect_tlv(uint8_t tlv)1868 static bool nfa_rw_detect_tlv(uint8_t tlv) {
1869   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1870 
1871   switch (nfa_rw_cb.protocol) {
1872     case NFC_PROTOCOL_T1T:
1873       if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
1874         nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
1875       break;
1876 
1877     case NFC_PROTOCOL_T2T:
1878       if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1879         if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
1880           nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
1881       }
1882       break;
1883 
1884     default:
1885       break;
1886   }
1887 
1888   return true;
1889 }
1890 
1891 /*******************************************************************************
1892 **
1893 ** Function         nfa_rw_config_tag_ro
1894 **
1895 ** Description      Handler for NFA_RW_OP_SET_TAG_RO
1896 **
1897 ** Returns          TRUE (message buffer to be freed by caller)
1898 **
1899 *******************************************************************************/
nfa_rw_config_tag_ro(bool b_hard_lock)1900 static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock) {
1901   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1902   tNFC_STATUS status = NFC_STATUS_FAILED;
1903 
1904   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1905 
1906   if (NFC_PROTOCOL_T1T == protocol) {
1907     /* Type1Tag    - NFC-A */
1908     if ((nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) ||
1909         (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE)) {
1910       status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
1911       return (status);
1912     } else {
1913       status = RW_T1tSetTagReadOnly(b_hard_lock);
1914     }
1915   } else if (NFC_PROTOCOL_T2T == protocol) {
1916     /* Type2Tag    - NFC-A */
1917     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
1918       status = RW_T2tSetTagReadOnly(b_hard_lock);
1919     }
1920   } else if (NFC_PROTOCOL_T3T == protocol) {
1921     /* Type3Tag    - NFC-F */
1922     status = RW_T3tSetReadOnly(b_hard_lock);
1923   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
1924     /* ISODEP/4A,4B- NFC-A or NFC-B */
1925     status = RW_T4tSetNDefReadOnly();
1926   } else if (NFC_PROTOCOL_T5T == protocol) {
1927     /* ISO 15693 */
1928     status = RW_I93SetTagReadOnly();
1929   }
1930 
1931   if (status == NFC_STATUS_OK) {
1932     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1933   } else {
1934     nfa_rw_error_cleanup(NFA_SET_TAG_RO_EVT);
1935   }
1936 
1937   return (status);
1938 }
1939 
1940 /*******************************************************************************
1941 **
1942 ** Function         nfa_rw_t1t_rid
1943 **
1944 ** Description      Handler for T1T_RID API
1945 **
1946 ** Returns          TRUE (message buffer to be freed by caller)
1947 **
1948 *******************************************************************************/
nfa_rw_t1t_rid()1949 static bool nfa_rw_t1t_rid() {
1950   if (RW_T1tRid() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
1951 
1952   return true;
1953 }
1954 
1955 /*******************************************************************************
1956 **
1957 ** Function         nfa_rw_t1t_rall
1958 **
1959 ** Description      Handler for T1T_ReadAll API
1960 **
1961 ** Returns          TRUE (message buffer to be freed by caller)
1962 **
1963 *******************************************************************************/
nfa_rw_t1t_rall()1964 static bool nfa_rw_t1t_rall() {
1965   if (RW_T1tReadAll() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
1966 
1967   return true;
1968 }
1969 
1970 /*******************************************************************************
1971 **
1972 ** Function         nfa_rw_t1t_read
1973 **
1974 ** Description      Handler for T1T_Read API
1975 **
1976 ** Returns          TRUE (message buffer to be freed by caller)
1977 **
1978 *******************************************************************************/
nfa_rw_t1t_read(tNFA_RW_MSG * p_data)1979 static bool nfa_rw_t1t_read(tNFA_RW_MSG* p_data) {
1980   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
1981       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
1982 
1983   if (RW_T1tRead(p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
1984     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
1985 
1986   return true;
1987 }
1988 
1989 /*******************************************************************************
1990 **
1991 ** Function         nfa_rw_t1t_write
1992 **
1993 ** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
1994 **
1995 ** Returns          TRUE (message buffer to be freed by caller)
1996 **
1997 *******************************************************************************/
nfa_rw_t1t_write(tNFA_RW_MSG * p_data)1998 static bool nfa_rw_t1t_write(tNFA_RW_MSG* p_data) {
1999   tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
2000       (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
2001   tNFC_STATUS status;
2002 
2003   if (p_t1t_write->b_erase) {
2004     status = RW_T1tWriteErase(p_t1t_write->block_number, p_t1t_write->index,
2005                               p_t1t_write->p_block_data[0]);
2006   } else {
2007     status = RW_T1tWriteNoErase(p_t1t_write->block_number, p_t1t_write->index,
2008                                 p_t1t_write->p_block_data[0]);
2009   }
2010 
2011   if (status != NFC_STATUS_OK) {
2012     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
2013   } else {
2014     if (p_t1t_write->block_number == 0x01)
2015       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2016   }
2017 
2018   return true;
2019 }
2020 
2021 /*******************************************************************************
2022 **
2023 ** Function         nfa_rw_t1t_rseg
2024 **
2025 ** Description      Handler for T1t_ReadSeg API
2026 **
2027 ** Returns          TRUE (message buffer to be freed by caller)
2028 **
2029 *******************************************************************************/
nfa_rw_t1t_rseg(tNFA_RW_MSG * p_data)2030 static bool nfa_rw_t1t_rseg(tNFA_RW_MSG* p_data) {
2031   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
2032       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
2033 
2034   if (RW_T1tReadSeg(p_t1t_read->segment_number) != NFC_STATUS_OK)
2035     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
2036 
2037   return true;
2038 }
2039 
2040 /*******************************************************************************
2041 **
2042 ** Function         nfa_rw_t1t_read8
2043 **
2044 ** Description      Handler for T1T_Read8 API
2045 **
2046 ** Returns          TRUE (message buffer to be freed by caller)
2047 **
2048 *******************************************************************************/
nfa_rw_t1t_read8(tNFA_RW_MSG * p_data)2049 static bool nfa_rw_t1t_read8(tNFA_RW_MSG* p_data) {
2050   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
2051       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
2052 
2053   if (RW_T1tRead8(p_t1t_read->block_number) != NFC_STATUS_OK)
2054     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
2055 
2056   return true;
2057 }
2058 
2059 /*******************************************************************************
2060 **
2061 ** Function         nfa_rw_t1t_write8
2062 **
2063 ** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
2064 **
2065 ** Returns          TRUE (message buffer to be freed by caller)
2066 **
2067 *******************************************************************************/
nfa_rw_t1t_write8(tNFA_RW_MSG * p_data)2068 static bool nfa_rw_t1t_write8(tNFA_RW_MSG* p_data) {
2069   tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
2070       (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
2071   tNFC_STATUS status;
2072 
2073   if (p_t1t_write->b_erase) {
2074     status =
2075         RW_T1tWriteErase8(p_t1t_write->block_number, p_t1t_write->p_block_data);
2076   } else {
2077     status = RW_T1tWriteNoErase8(p_t1t_write->block_number,
2078                                  p_t1t_write->p_block_data);
2079   }
2080 
2081   if (status != NFC_STATUS_OK) {
2082     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
2083   } else {
2084     if (p_t1t_write->block_number == 0x01)
2085       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2086   }
2087 
2088   return true;
2089 }
2090 
2091 /*******************************************************************************
2092 **
2093 ** Function         nfa_rw_t2t_read
2094 **
2095 ** Description      Handler for T2T_Read API
2096 **
2097 ** Returns          TRUE (message buffer to be freed by caller)
2098 **
2099 *******************************************************************************/
nfa_rw_t2t_read(tNFA_RW_MSG * p_data)2100 static bool nfa_rw_t2t_read(tNFA_RW_MSG* p_data) {
2101   tNFA_RW_OP_PARAMS_T2T_READ* p_t2t_read =
2102       (tNFA_RW_OP_PARAMS_T2T_READ*)&(p_data->op_req.params.t2t_read);
2103   tNFC_STATUS status = NFC_STATUS_FAILED;
2104 
2105   if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
2106     status = RW_T2tRead(p_t2t_read->block_number);
2107 
2108   if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
2109 
2110   return true;
2111 }
2112 
2113 /*******************************************************************************
2114 **
2115 ** Function         nfa_rw_t2t_write
2116 **
2117 ** Description      Handler for T2T_Write API
2118 **
2119 ** Returns          TRUE (message buffer to be freed by caller)
2120 **
2121 *******************************************************************************/
nfa_rw_t2t_write(tNFA_RW_MSG * p_data)2122 static bool nfa_rw_t2t_write(tNFA_RW_MSG* p_data) {
2123   tNFA_RW_OP_PARAMS_T2T_WRITE* p_t2t_write =
2124       (tNFA_RW_OP_PARAMS_T2T_WRITE*)&(p_data->op_req.params.t2t_write);
2125 
2126   if (RW_T2tWrite(p_t2t_write->block_number, p_t2t_write->p_block_data) !=
2127       NFC_STATUS_OK) {
2128     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
2129   } else {
2130     if (p_t2t_write->block_number == 0x03)
2131       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2132   }
2133 
2134   return true;
2135 }
2136 
2137 /*******************************************************************************
2138 **
2139 ** Function         nfa_rw_t2t_sector_select
2140 **
2141 ** Description      Handler for T2T_Sector_Select API
2142 **
2143 ** Returns          TRUE (message buffer to be freed by caller)
2144 **
2145 *******************************************************************************/
nfa_rw_t2t_sector_select(tNFA_RW_MSG * p_data)2146 static bool nfa_rw_t2t_sector_select(tNFA_RW_MSG* p_data) {
2147   tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT* p_t2t_sector_select =
2148       (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT*)&(
2149           p_data->op_req.params.t2t_sector_select);
2150 
2151   if (RW_T2tSectorSelect(p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
2152     nfa_rw_error_cleanup(NFA_SELECT_CPLT_EVT);
2153 
2154   return true;
2155 }
2156 
2157 /*******************************************************************************
2158 **
2159 ** Function         nfa_rw_t3t_read
2160 **
2161 ** Description      Handler for T3T_Read API
2162 **
2163 ** Returns          TRUE (message buffer to be freed by caller)
2164 **
2165 *******************************************************************************/
nfa_rw_t3t_read(tNFA_RW_MSG * p_data)2166 static bool nfa_rw_t3t_read(tNFA_RW_MSG* p_data) {
2167   tNFA_RW_OP_PARAMS_T3T_READ* p_t3t_read =
2168       (tNFA_RW_OP_PARAMS_T3T_READ*)&(p_data->op_req.params.t3t_read);
2169 
2170   if (RW_T3tCheck(p_t3t_read->num_blocks,
2171                   (tT3T_BLOCK_DESC*)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
2172     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
2173 
2174   return true;
2175 }
2176 
2177 /*******************************************************************************
2178 **
2179 ** Function         nfa_rw_t3t_write
2180 **
2181 ** Description      Handler for T3T_Write API
2182 **
2183 ** Returns          TRUE (message buffer to be freed by caller)
2184 **
2185 *******************************************************************************/
nfa_rw_t3t_write(tNFA_RW_MSG * p_data)2186 static bool nfa_rw_t3t_write(tNFA_RW_MSG* p_data) {
2187   tNFA_RW_OP_PARAMS_T3T_WRITE* p_t3t_write =
2188       (tNFA_RW_OP_PARAMS_T3T_WRITE*)&(p_data->op_req.params.t3t_write);
2189 
2190   if (RW_T3tUpdate(p_t3t_write->num_blocks,
2191                    (tT3T_BLOCK_DESC*)p_t3t_write->p_block_desc,
2192                    p_t3t_write->p_block_data) != NFC_STATUS_OK)
2193     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
2194 
2195   return true;
2196 }
2197 
2198 /*******************************************************************************
2199 **
2200 ** Function         nfa_rw_t3t_get_system_codes
2201 **
2202 ** Description      Get system codes (initiated by NFA after activation)
2203 **
2204 ** Returns          TRUE (message buffer to be freed by caller)
2205 **
2206 *******************************************************************************/
nfa_rw_t3t_get_system_codes()2207 static bool nfa_rw_t3t_get_system_codes() {
2208   tNFC_STATUS status;
2209   tNFA_TAG_PARAMS tag_params;
2210 
2211   status = RW_T3tGetSystemCodes();
2212 
2213   if (status != NFC_STATUS_OK) {
2214     /* Command complete - perform cleanup, notify app */
2215     nfa_rw_command_complete();
2216     tag_params.t3t.num_system_codes = 0;
2217     tag_params.t3t.p_system_codes = NULL;
2218 
2219     nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
2220   }
2221 
2222   return true;
2223 }
2224 
2225 /*******************************************************************************
2226 **
2227 ** Function         nfa_rw_i93_command
2228 **
2229 ** Description      Handler for ISO 15693 command
2230 **
2231 ** Returns          TRUE (message buffer to be freed by caller)
2232 **
2233 *******************************************************************************/
nfa_rw_i93_command(tNFA_RW_MSG * p_data)2234 static bool nfa_rw_i93_command(tNFA_RW_MSG* p_data) {
2235   tNFA_CONN_EVT_DATA conn_evt_data;
2236   tNFC_STATUS status = NFC_STATUS_OK;
2237   uint8_t i93_command = I93_CMD_STAY_QUIET;
2238 
2239   switch (p_data->op_req.op) {
2240     case NFA_RW_OP_I93_INVENTORY:
2241       i93_command = I93_CMD_INVENTORY;
2242       if (p_data->op_req.params.i93_cmd.uid_present) {
2243         status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
2244                                  p_data->op_req.params.i93_cmd.afi,
2245                                  p_data->op_req.params.i93_cmd.uid);
2246       } else {
2247         status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
2248                                  p_data->op_req.params.i93_cmd.afi, NULL);
2249       }
2250       break;
2251 
2252     case NFA_RW_OP_I93_STAY_QUIET:
2253       i93_command = I93_CMD_STAY_QUIET;
2254       status = RW_I93StayQuiet();
2255       break;
2256 
2257     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2258       i93_command = I93_CMD_READ_SINGLE_BLOCK;
2259       status = RW_I93ReadSingleBlock(
2260           p_data->op_req.params.i93_cmd.first_block_number);
2261       break;
2262 
2263     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2264       i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
2265       status = RW_I93WriteSingleBlock(
2266           p_data->op_req.params.i93_cmd.first_block_number,
2267           p_data->op_req.params.i93_cmd.p_data);
2268       break;
2269 
2270     case NFA_RW_OP_I93_LOCK_BLOCK:
2271       i93_command = I93_CMD_LOCK_BLOCK;
2272       status = RW_I93LockBlock(
2273           (uint8_t)p_data->op_req.params.i93_cmd.first_block_number);
2274       break;
2275 
2276     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2277       i93_command = I93_CMD_READ_MULTI_BLOCK;
2278       status = RW_I93ReadMultipleBlocks(
2279           p_data->op_req.params.i93_cmd.first_block_number,
2280           p_data->op_req.params.i93_cmd.number_blocks);
2281       break;
2282 
2283     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2284       i93_command = I93_CMD_WRITE_MULTI_BLOCK;
2285       status = RW_I93WriteMultipleBlocks(
2286           (uint8_t)p_data->op_req.params.i93_cmd.first_block_number,
2287           p_data->op_req.params.i93_cmd.number_blocks,
2288           p_data->op_req.params.i93_cmd.p_data);
2289       break;
2290 
2291     case NFA_RW_OP_I93_SELECT:
2292       i93_command = I93_CMD_SELECT;
2293       status = RW_I93Select(p_data->op_req.params.i93_cmd.p_data);
2294       break;
2295 
2296     case NFA_RW_OP_I93_RESET_TO_READY:
2297       i93_command = I93_CMD_RESET_TO_READY;
2298       status = RW_I93ResetToReady();
2299       break;
2300 
2301     case NFA_RW_OP_I93_WRITE_AFI:
2302       i93_command = I93_CMD_WRITE_AFI;
2303       status = RW_I93WriteAFI(p_data->op_req.params.i93_cmd.afi);
2304       break;
2305 
2306     case NFA_RW_OP_I93_LOCK_AFI:
2307       i93_command = I93_CMD_LOCK_AFI;
2308       status = RW_I93LockAFI();
2309       break;
2310 
2311     case NFA_RW_OP_I93_WRITE_DSFID:
2312       i93_command = I93_CMD_WRITE_DSFID;
2313       status = RW_I93WriteDSFID(p_data->op_req.params.i93_cmd.dsfid);
2314       break;
2315 
2316     case NFA_RW_OP_I93_LOCK_DSFID:
2317       i93_command = I93_CMD_LOCK_DSFID;
2318       status = RW_I93LockDSFID();
2319       break;
2320 
2321     case NFA_RW_OP_I93_GET_SYS_INFO:
2322       i93_command = I93_CMD_GET_SYS_INFO;
2323       if (p_data->op_req.params.i93_cmd.uid_present) {
2324         status = RW_I93GetSysInfo(p_data->op_req.params.i93_cmd.uid);
2325       } else {
2326         status = RW_I93GetSysInfo(NULL);
2327       }
2328       break;
2329 
2330     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2331       i93_command = I93_CMD_GET_MULTI_BLK_SEC;
2332       status = RW_I93GetMultiBlockSecurityStatus(
2333           p_data->op_req.params.i93_cmd.first_block_number,
2334           p_data->op_req.params.i93_cmd.number_blocks);
2335       break;
2336 
2337     default:
2338       break;
2339   }
2340 
2341   if (status != NFC_STATUS_OK) {
2342     /* Command complete - perform cleanup, notify app */
2343     nfa_rw_command_complete();
2344 
2345     conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED;
2346     conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
2347 
2348     nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
2349   }
2350 
2351   return true;
2352 }
2353 
2354 /*******************************************************************************
2355 **
2356 ** Function         nfa_rw_raw_mode_data_cback
2357 **
2358 ** Description      Handler for incoming tag data for unsupported tag protocols
2359 **                  (forward data to upper layer)
2360 **
2361 ** Returns          nothing
2362 **
2363 *******************************************************************************/
nfa_rw_raw_mode_data_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2364 static void nfa_rw_raw_mode_data_cback(__attribute__((unused)) uint8_t conn_id,
2365                                        tNFC_CONN_EVT event, tNFC_CONN* p_data) {
2366   NFC_HDR* p_msg;
2367   tNFA_CONN_EVT_DATA evt_data;
2368 
2369   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event = 0x%X", event);
2370 
2371   if ((event == NFC_DATA_CEVT) &&
2372       ((p_data->data.status == NFC_STATUS_OK) ||
2373        (p_data->data.status == NFC_STATUS_CONTINUE))) {
2374     p_msg = (NFC_HDR*)p_data->data.p_data;
2375 
2376     if (p_msg) {
2377       evt_data.data.status = p_data->data.status;
2378       evt_data.data.p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
2379       evt_data.data.len = p_msg->len;
2380 
2381       nfa_dm_conn_cback_event_notify(NFA_DATA_EVT, &evt_data);
2382 
2383       GKI_freebuf(p_msg);
2384     } else {
2385       LOG(ERROR) << StringPrintf(
2386           "received NFC_DATA_CEVT with NULL data pointer");
2387     }
2388   } else if (event == NFC_DEACTIVATE_CEVT) {
2389     NFC_SetStaticRfCback(NULL);
2390   }
2391 }
2392 
2393 /*******************************************************************************
2394 **
2395 ** Function         nfa_rw_activate_ntf
2396 **
2397 ** Description      Handler for NFA_RW_ACTIVATE_NTF
2398 **
2399 ** Returns          TRUE (message buffer to be freed by caller)
2400 **
2401 *******************************************************************************/
nfa_rw_activate_ntf(tNFA_RW_MSG * p_data)2402 bool nfa_rw_activate_ntf(tNFA_RW_MSG* p_data) {
2403   tNFC_ACTIVATE_DEVT* p_activate_params =
2404       p_data->activate_ntf.p_activate_params;
2405   tNFA_TAG_PARAMS tag_params;
2406   bool activate_notify = true;
2407   uint8_t* p;
2408 
2409   if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
2410       (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
2411       (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
2412       (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
2413     /* Type 2 tag is wake up from HALT State */
2414     if (nfa_dm_cb.p_activate_ntf != NULL) {
2415       GKI_freebuf(nfa_dm_cb.p_activate_ntf);
2416       nfa_dm_cb.p_activate_ntf = NULL;
2417     }
2418     DLOG_IF(INFO, nfc_debug_enabled)
2419         << StringPrintf("- Type 2 tag wake up from HALT State");
2420     return true;
2421   }
2422 
2423   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
2424 
2425   /* Initialize control block */
2426   nfa_rw_cb.protocol = p_activate_params->protocol;
2427   nfa_rw_cb.intf_type = p_activate_params->intf_param.type;
2428   nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
2429   nfa_rw_cb.activated_tech_mode = p_activate_params->rf_tech_param.mode;
2430   nfa_rw_cb.flags = NFA_RW_FL_ACTIVATED;
2431   nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
2432   nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
2433   nfa_rw_cb.skip_dyn_locks = false;
2434   nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2435   nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
2436 
2437   memset(&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
2438 
2439   /* Check if we are in exclusive RF mode */
2440   if (p_data->activate_ntf.excl_rf_not_active) {
2441     /* Not in exclusive RF mode */
2442     nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
2443   }
2444 
2445   /* check if the protocol is activated with supported interface */
2446   if (p_activate_params->intf_param.type == NCI_INTERFACE_FRAME) {
2447     if ((p_activate_params->protocol != NFA_PROTOCOL_T1T) &&
2448         (p_activate_params->protocol != NFA_PROTOCOL_T2T) &&
2449         (p_activate_params->protocol != NFA_PROTOCOL_T3T) &&
2450         (p_activate_params->protocol != NFA_PROTOCOL_T5T)) {
2451       nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
2452     }
2453   } else if (p_activate_params->intf_param.type == NCI_INTERFACE_ISO_DEP) {
2454     if (p_activate_params->protocol != NFA_PROTOCOL_ISO_DEP) {
2455       nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
2456     }
2457   }
2458 
2459   if (nfa_rw_cb.protocol == NFA_PROTOCOL_INVALID) {
2460     /* Only sending raw frame and presence check are supported in this state */
2461 
2462     NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
2463 
2464     /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
2465     nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
2466     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
2467     return true;
2468   }
2469 
2470   /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and
2471    * start presence check if needed */
2472   if (!nfa_dm_is_protocol_supported(
2473           p_activate_params->protocol,
2474           p_activate_params->rf_tech_param.param.pa.sel_rsp)) {
2475     /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence
2476      * check timer */
2477     /* Set data callback (pass all incoming data to upper layer using
2478      * NFA_DATA_EVT) */
2479     NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
2480 
2481     /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
2482     nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
2483     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
2484     return true;
2485   }
2486 
2487   /* Initialize RW module */
2488   if ((RW_SetActivatedTagType(p_activate_params, nfa_rw_cback)) !=
2489       NFC_STATUS_OK) {
2490     /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
2491     LOG(ERROR) << StringPrintf("RW_SetActivatedTagType failed.");
2492     return true;
2493   }
2494 
2495   /* Perform protocol-specific actions */
2496   if (NFC_PROTOCOL_T1T == nfa_rw_cb.protocol) {
2497     /* Retrieve HR and UID fields from activation notification */
2498     memcpy(tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
2499            p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2500 
2501     if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
2502       memcpy(tag_params.t1t.hr, p_activate_params->rf_tech_param.param.pa.hr,
2503              NFA_T1T_HR_LEN);
2504     } else {
2505       memcpy(tag_params.t1t.hr,
2506              p_activate_params->intf_param.intf_param.frame.param,
2507              NFA_T1T_HR_LEN);
2508       tNFA_RW_MSG msg;
2509       msg.op_req.op = NFA_RW_OP_T1T_RID;
2510       nfa_rw_handle_op_req(&msg);
2511       /* Delay notifying upper layer of NFA_ACTIVATED_EVT
2512          until HR0/HR1 is received */
2513       activate_notify = false;
2514     }
2515   } else if (NFC_PROTOCOL_T2T == nfa_rw_cb.protocol) {
2516     /* Retrieve UID fields from activation notification */
2517     memcpy(tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
2518            p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2519   } else if (NFC_PROTOCOL_T3T == nfa_rw_cb.protocol) {
2520     if (appl_dta_mode_flag) {
2521       /* Incase of DTA mode Dont send commands to get system code. Just notify
2522        * activation */
2523       activate_notify = true;
2524     } else {
2525       /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes
2526        * are retrieved */
2527       activate_notify = false;
2528 
2529       /* Issue command to get Felica system codes */
2530       tNFA_RW_MSG msg;
2531       msg.op_req.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
2532       nfa_rw_handle_op_req(&msg);
2533     }
2534   } else if (NFA_PROTOCOL_T5T == nfa_rw_cb.protocol) {
2535     /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional
2536      * tag infomation */
2537     nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
2538     activate_notify = false;
2539 
2540     /* store DSFID and UID from activation NTF */
2541     nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid;
2542 
2543     p = nfa_rw_cb.i93_uid;
2544     ARRAY8_TO_STREAM(p, p_activate_params->rf_tech_param.param.pi93.uid);
2545 
2546     if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI) &&
2547         (((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
2548           I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) ||
2549          ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
2550           I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY))) {
2551       /* these don't support Get System Information Command */
2552       nfa_rw_cb.i93_block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
2553       nfa_rw_cb.i93_afi_location =
2554           I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2555 
2556       if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
2557           I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) {
2558         nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
2559       } else {
2560         nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
2561       }
2562 
2563       /* read AFI */
2564       if (RW_I93ReadSingleBlock((uint8_t)(nfa_rw_cb.i93_afi_location /
2565                                           nfa_rw_cb.i93_block_size)) !=
2566           NFC_STATUS_OK) {
2567         /* notify activation without AFI/IC-Ref */
2568         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2569         activate_notify = true;
2570 
2571         tag_params.i93.info_flags =
2572             (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE);
2573         tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
2574         tag_params.i93.block_size = nfa_rw_cb.i93_block_size;
2575         tag_params.i93.num_block = nfa_rw_cb.i93_num_block;
2576         memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2577       }
2578     } else {
2579       /* All of ICODE supports Get System Information Command */
2580       /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
2581       /* just try for others */
2582 
2583       if (RW_I93GetSysInfo(nfa_rw_cb.i93_uid) != NFC_STATUS_OK) {
2584         /* notify activation without AFI/MEM size/IC-Ref */
2585         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2586         activate_notify = true;
2587 
2588         tag_params.i93.info_flags = I93_INFO_FLAG_DSFID;
2589         tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
2590         tag_params.i93.block_size = 0;
2591         tag_params.i93.num_block = 0;
2592         memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2593       } else {
2594         /* reset memory size */
2595         nfa_rw_cb.i93_block_size = 0;
2596         nfa_rw_cb.i93_num_block = 0;
2597       }
2598     }
2599   }
2600 
2601   /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check
2602    * timer */
2603   if (activate_notify) {
2604     nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
2605     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
2606   }
2607 
2608   return true;
2609 }
2610 
2611 /*******************************************************************************
2612 **
2613 ** Function         nfa_rw_deactivate_ntf
2614 **
2615 ** Description      Handler for NFA_RW_DEACTIVATE_NTF
2616 **
2617 ** Returns          TRUE (message buffer to be freed by caller)
2618 **
2619 *******************************************************************************/
nfa_rw_deactivate_ntf(tNFA_RW_MSG * p_data)2620 bool nfa_rw_deactivate_ntf(__attribute__((unused)) tNFA_RW_MSG* p_data) {
2621   /* Clear the activated flag */
2622   nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
2623 
2624   /* Free buffer for incoming NDEF message, in case we were in the middle of a
2625    * read operation */
2626   nfa_rw_free_ndef_rx_buf();
2627 
2628   /* If there is a pending command message, then free it */
2629   if (nfa_rw_cb.p_pending_msg) {
2630     if ((nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_SEND_RAW_FRAME) &&
2631         (nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data)) {
2632       GKI_freebuf(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data);
2633     }
2634 
2635     GKI_freebuf(nfa_rw_cb.p_pending_msg);
2636     nfa_rw_cb.p_pending_msg = NULL;
2637   }
2638 
2639   /* If we are in the process of waking up tag from HALT state */
2640   if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
2641     if (nfa_rw_cb.rw_data.data.p_data)
2642       GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
2643     nfa_rw_cb.rw_data.data.p_data = NULL;
2644   }
2645 
2646   /* Stop presence check timer (if started) */
2647   nfa_rw_stop_presence_check_timer();
2648 
2649   return true;
2650 }
2651 
2652 /*******************************************************************************
2653 **
2654 ** Function         nfa_rw_handle_op_req
2655 **
2656 ** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
2657 **
2658 ** Returns          TRUE if caller should free p_data
2659 **                  FALSE if caller does not need to free p_data
2660 **
2661 *******************************************************************************/
nfa_rw_handle_op_req(tNFA_RW_MSG * p_data)2662 bool nfa_rw_handle_op_req(tNFA_RW_MSG* p_data) {
2663   bool freebuf = true;
2664   uint16_t presence_check_start_delay = 0;
2665 
2666   /* Check if activated */
2667   if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)) {
2668     LOG(ERROR) << StringPrintf("nfa_rw_handle_op_req: not activated");
2669     return true;
2670   }
2671   /* Check if currently busy with another API call */
2672   else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) {
2673     return (nfa_rw_op_req_while_busy(p_data));
2674   }
2675   /* Check if currently busy with auto-presence check */
2676   else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
2677     /* Cache the command (will be handled once auto-presence check is completed)
2678      */
2679     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2680         "Deferring operation %i until after auto-presence check is completed",
2681         p_data->op_req.op);
2682     nfa_rw_cb.p_pending_msg = p_data;
2683     nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2684     return false;
2685   }
2686 
2687   DLOG_IF(INFO, nfc_debug_enabled)
2688       << StringPrintf("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
2689 
2690   nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2691 
2692   /* Stop the presence check timer */
2693   nfa_rw_stop_presence_check_timer();
2694 
2695   /* Store the current operation */
2696   nfa_rw_cb.cur_op = p_data->op_req.op;
2697 
2698   /* Call appropriate handler for requested operation */
2699   switch (p_data->op_req.op) {
2700     case NFA_RW_OP_DETECT_NDEF:
2701       nfa_rw_cb.skip_dyn_locks = false;
2702       nfa_rw_detect_ndef();
2703       break;
2704 
2705     case NFA_RW_OP_READ_NDEF:
2706       nfa_rw_read_ndef();
2707       break;
2708 
2709     case NFA_RW_OP_WRITE_NDEF:
2710       nfa_rw_write_ndef(p_data);
2711       break;
2712 
2713     case NFA_RW_OP_SEND_RAW_FRAME:
2714       presence_check_start_delay =
2715           p_data->op_req.params.send_raw_frame.p_data->layer_specific;
2716 
2717       NFC_SendData(NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
2718 
2719       /* Clear the busy flag */
2720       nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
2721 
2722       /* Start presence_check after specified delay */
2723       nfa_rw_check_start_presence_check_timer(presence_check_start_delay);
2724       break;
2725 
2726     case NFA_RW_OP_PRESENCE_CHECK:
2727       nfa_rw_presence_check(p_data);
2728       break;
2729 
2730     case NFA_RW_OP_FORMAT_TAG:
2731       nfa_rw_format_tag();
2732       break;
2733 
2734     case NFA_RW_OP_DETECT_LOCK_TLV:
2735       nfa_rw_detect_tlv(TAG_LOCK_CTRL_TLV);
2736       break;
2737 
2738     case NFA_RW_OP_DETECT_MEM_TLV:
2739       nfa_rw_detect_tlv(TAG_MEM_CTRL_TLV);
2740       break;
2741 
2742     case NFA_RW_OP_SET_TAG_RO:
2743       nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
2744       nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
2745       break;
2746 
2747     case NFA_RW_OP_T1T_RID:
2748       nfa_rw_t1t_rid();
2749       break;
2750 
2751     case NFA_RW_OP_T1T_RALL:
2752       nfa_rw_t1t_rall();
2753       break;
2754 
2755     case NFA_RW_OP_T1T_READ:
2756       nfa_rw_t1t_read(p_data);
2757       break;
2758 
2759     case NFA_RW_OP_T1T_WRITE:
2760       nfa_rw_t1t_write(p_data);
2761       break;
2762 
2763     case NFA_RW_OP_T1T_RSEG:
2764       nfa_rw_t1t_rseg(p_data);
2765       break;
2766 
2767     case NFA_RW_OP_T1T_READ8:
2768       nfa_rw_t1t_read8(p_data);
2769       break;
2770 
2771     case NFA_RW_OP_T1T_WRITE8:
2772       nfa_rw_t1t_write8(p_data);
2773       break;
2774 
2775     /* Type-2 tag commands */
2776     case NFA_RW_OP_T2T_READ:
2777       nfa_rw_t2t_read(p_data);
2778       break;
2779 
2780     case NFA_RW_OP_T2T_WRITE:
2781       nfa_rw_t2t_write(p_data);
2782       break;
2783 
2784     case NFA_RW_OP_T2T_SECTOR_SELECT:
2785       nfa_rw_t2t_sector_select(p_data);
2786       break;
2787 
2788     /* Type-3 tag commands */
2789     case NFA_RW_OP_T3T_READ:
2790       nfa_rw_t3t_read(p_data);
2791       break;
2792 
2793     case NFA_RW_OP_T3T_WRITE:
2794       nfa_rw_t3t_write(p_data);
2795       break;
2796 
2797     case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
2798       nfa_rw_t3t_get_system_codes();
2799       break;
2800 
2801     /* ISO 15693 tag commands */
2802     case NFA_RW_OP_I93_INVENTORY:
2803     case NFA_RW_OP_I93_STAY_QUIET:
2804     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2805     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2806     case NFA_RW_OP_I93_LOCK_BLOCK:
2807     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2808     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2809     case NFA_RW_OP_I93_SELECT:
2810     case NFA_RW_OP_I93_RESET_TO_READY:
2811     case NFA_RW_OP_I93_WRITE_AFI:
2812     case NFA_RW_OP_I93_LOCK_AFI:
2813     case NFA_RW_OP_I93_WRITE_DSFID:
2814     case NFA_RW_OP_I93_LOCK_DSFID:
2815     case NFA_RW_OP_I93_GET_SYS_INFO:
2816     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2817       nfa_rw_i93_command(p_data);
2818       break;
2819 
2820     default:
2821       LOG(ERROR) << StringPrintf("nfa_rw_handle_api: unhandled operation: %i",
2822                                  p_data->op_req.op);
2823       break;
2824   }
2825 
2826   return (freebuf);
2827 }
2828 
2829 /*******************************************************************************
2830 **
2831 ** Function         nfa_rw_op_req_while_busy
2832 **
2833 ** Description      Handle operation request while busy
2834 **
2835 ** Returns          TRUE if caller should free p_data
2836 **                  FALSE if caller does not need to free p_data
2837 **
2838 *******************************************************************************/
nfa_rw_op_req_while_busy(tNFA_RW_MSG * p_data)2839 static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data) {
2840   bool freebuf = true;
2841   tNFA_CONN_EVT_DATA conn_evt_data;
2842   uint8_t event;
2843 
2844   LOG(ERROR) << StringPrintf("nfa_rw_op_req_while_busy: unable to handle API");
2845 
2846   /* Return appropriate event for requested API, with status=BUSY */
2847   conn_evt_data.status = NFA_STATUS_BUSY;
2848 
2849   switch (p_data->op_req.op) {
2850     case NFA_RW_OP_DETECT_NDEF:
2851       conn_evt_data.ndef_detect.cur_size = 0;
2852       conn_evt_data.ndef_detect.max_size = 0;
2853       conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
2854       event = NFA_NDEF_DETECT_EVT;
2855       break;
2856     case NFA_RW_OP_READ_NDEF:
2857     case NFA_RW_OP_T1T_RID:
2858     case NFA_RW_OP_T1T_RALL:
2859     case NFA_RW_OP_T1T_READ:
2860     case NFA_RW_OP_T1T_RSEG:
2861     case NFA_RW_OP_T1T_READ8:
2862     case NFA_RW_OP_T2T_READ:
2863     case NFA_RW_OP_T3T_READ:
2864       event = NFA_READ_CPLT_EVT;
2865       break;
2866     case NFA_RW_OP_WRITE_NDEF:
2867     case NFA_RW_OP_T1T_WRITE:
2868     case NFA_RW_OP_T1T_WRITE8:
2869     case NFA_RW_OP_T2T_WRITE:
2870     case NFA_RW_OP_T3T_WRITE:
2871       event = NFA_WRITE_CPLT_EVT;
2872       break;
2873     case NFA_RW_OP_FORMAT_TAG:
2874       event = NFA_FORMAT_CPLT_EVT;
2875       break;
2876     case NFA_RW_OP_DETECT_LOCK_TLV:
2877     case NFA_RW_OP_DETECT_MEM_TLV:
2878       event = NFA_TLV_DETECT_EVT;
2879       break;
2880     case NFA_RW_OP_SET_TAG_RO:
2881       event = NFA_SET_TAG_RO_EVT;
2882       break;
2883     case NFA_RW_OP_T2T_SECTOR_SELECT:
2884       event = NFA_SELECT_CPLT_EVT;
2885       break;
2886     case NFA_RW_OP_I93_INVENTORY:
2887     case NFA_RW_OP_I93_STAY_QUIET:
2888     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2889     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2890     case NFA_RW_OP_I93_LOCK_BLOCK:
2891     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2892     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2893     case NFA_RW_OP_I93_SELECT:
2894     case NFA_RW_OP_I93_RESET_TO_READY:
2895     case NFA_RW_OP_I93_WRITE_AFI:
2896     case NFA_RW_OP_I93_LOCK_AFI:
2897     case NFA_RW_OP_I93_WRITE_DSFID:
2898     case NFA_RW_OP_I93_LOCK_DSFID:
2899     case NFA_RW_OP_I93_GET_SYS_INFO:
2900     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2901       event = NFA_I93_CMD_CPLT_EVT;
2902       break;
2903     default:
2904       return (freebuf);
2905   }
2906   nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
2907 
2908   return (freebuf);
2909 }
2910 
2911 /*******************************************************************************
2912 **
2913 ** Function         nfa_rw_command_complete
2914 **
2915 ** Description      Handle command complete: clear the busy flag,
2916 **                  and start the presence check timer if applicable.
2917 **
2918 ** Returns          None
2919 **
2920 *******************************************************************************/
nfa_rw_command_complete(void)2921 void nfa_rw_command_complete(void) {
2922   /* Clear the busy flag */
2923   nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
2924 
2925   /* Restart presence_check timer */
2926   nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
2927 }
2928