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