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