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