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