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