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