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