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