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