1 /******************************************************************************
2 *
3 * Copyright (C) 2011-2013 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19
20 /******************************************************************************
21 *
22 * This file contains the action functions the NFA_CE state machine.
23 *
24 ******************************************************************************/
25 #include <string.h>
26 #include "nfa_ce_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 "ce_api.h"
32 #if (NFC_NFCEE_INCLUDED == TRUE)
33 #include "nfa_ee_int.h"
34 #endif
35
36 /*****************************************************************************
37 * Protocol-specific event handlers
38 *****************************************************************************/
39
40 /*******************************************************************************
41 **
42 ** Function nfa_ce_handle_t3t_evt
43 **
44 ** Description Handler for Type-3 tag card emulation events
45 **
46 ** Returns Nothing
47 **
48 *******************************************************************************/
nfa_ce_handle_t3t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)49 void nfa_ce_handle_t3t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
50 {
51 tNFA_CE_CB *p_cb = &nfa_ce_cb;
52 tNFA_CONN_EVT_DATA conn_evt;
53
54 NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt: event 0x%x", event);
55
56 switch (event)
57 {
58 case CE_T3T_NDEF_UPDATE_START_EVT:
59 /* Notify app using callback associated with the active ndef */
60 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
61 {
62 conn_evt.status = NFA_STATUS_OK;
63 (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
64 }
65 else
66 {
67 NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active NDEF");
68 }
69 break;
70
71 case CE_T3T_NDEF_UPDATE_CPLT_EVT:
72 /* Notify app using callback associated with the active ndef */
73 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
74 {
75 conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
76 conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
77 conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
78 (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
79 }
80 else
81 {
82 NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active NDEF");
83 }
84 break;
85
86 case CE_T3T_RAW_FRAME_EVT:
87 if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
88 {
89 conn_evt.data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
90 conn_evt.data.len = p_ce_data->raw_frame.p_data->len;
91 (*p_cb->p_active_conn_cback) (NFA_DATA_EVT, &conn_evt);
92 }
93 else
94 {
95 conn_evt.ce_data.handle = (NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active));
96 conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
97 conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
98 (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
99 }
100 GKI_freebuf (p_ce_data->raw_frame.p_data);
101 break;
102
103 default:
104 NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
105 break;
106 }
107 }
108
109 /*******************************************************************************
110 **
111 ** Function nfa_ce_handle_t4t_evt
112 **
113 ** Description Handler for Type-4 tag card emulation events (for NDEF case)
114 **
115 ** Returns Nothing
116 **
117 *******************************************************************************/
nfa_ce_handle_t4t_evt(tCE_EVENT event,tCE_DATA * p_ce_data)118 void nfa_ce_handle_t4t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
119 {
120 tNFA_CE_CB *p_cb = &nfa_ce_cb;
121 tNFA_CONN_EVT_DATA conn_evt;
122
123 NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt: event 0x%x", event);
124
125 /* AID for NDEF selected. we had notified the app of activation. */
126 p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
127 if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
128 {
129 p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
130 }
131
132 switch (event)
133 {
134 case CE_T4T_NDEF_UPDATE_START_EVT:
135 conn_evt.status = NFA_STATUS_OK;
136 (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
137 break;
138
139 case CE_T4T_NDEF_UPDATE_CPLT_EVT:
140 conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
141 conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
142
143 if (NDEF_MsgValidate (p_ce_data->update_info.p_data, p_ce_data->update_info.length, TRUE) != NDEF_OK)
144 conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
145 else
146 conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
147
148 (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
149 break;
150
151 case CE_T4T_NDEF_UPDATE_ABORT_EVT:
152 conn_evt.ndef_write_cplt.len = 0;
153 conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
154 conn_evt.ndef_write_cplt.p_data = NULL;
155 (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
156 break;
157
158 default:
159 /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
160 NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
161 break;
162 }
163 }
164
165
166 /*******************************************************************************
167 **
168 ** Function nfa_ce_handle_t4t_aid_evt
169 **
170 ** Description Handler for Type-4 tag AID events (for AIDs registered using
171 ** NFA_CeRegisterT4tAidOnDH)
172 **
173 ** Returns Nothing
174 **
175 *******************************************************************************/
nfa_ce_handle_t4t_aid_evt(tCE_EVENT event,tCE_DATA * p_ce_data)176 void nfa_ce_handle_t4t_aid_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
177 {
178 tNFA_CE_CB *p_cb = &nfa_ce_cb;
179 UINT8 listen_info_idx;
180 tNFA_CONN_EVT_DATA conn_evt;
181
182 NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
183
184 /* Get listen_info for this aid callback */
185 for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
186 {
187 if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
188 (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID) &&
189 (p_cb->listen_info[listen_info_idx].t4t_aid_handle == p_ce_data->raw_frame.aid_handle))
190 {
191 p_cb->idx_cur_active = listen_info_idx;
192 p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
193 break;
194 }
195 }
196
197 if (event == CE_T4T_RAW_FRAME_EVT)
198 {
199 if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
200 {
201 /* Found listen_info entry */
202 conn_evt.ce_activated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE) p_cb->idx_cur_active);
203
204 /* If we have not notified the app of activation, do so now */
205 if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
206 {
207 p_cb->listen_info[p_cb->idx_cur_active].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
208
209 memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
210 conn_evt.ce_activated.status = NFA_STATUS_OK;
211 (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
212 }
213
214 /* Notify app of AID data */
215 conn_evt.ce_data.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
216 conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
217 conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
218 (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
219 }
220 else
221 {
222 NFA_TRACE_ERROR1 ("nfa_ce_handle_t4t_aid_evt: unable to find listen_info for aid hdl %i", p_ce_data->raw_frame.aid_handle)
223 }
224
225 GKI_freebuf (p_ce_data->raw_frame.p_data);
226 }
227 }
228
229 /*****************************************************************************
230 * Discovery configuration and discovery event handlers
231 *****************************************************************************/
232
233 /*******************************************************************************
234 **
235 ** Function nfa_ce_discovery_cback
236 **
237 ** Description Processing event from discovery callback
238 **
239 ** Returns None
240 **
241 *******************************************************************************/
nfa_ce_discovery_cback(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data)242 void nfa_ce_discovery_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
243 {
244 tNFA_CE_MSG ce_msg;
245 NFA_TRACE_DEBUG1 ("nfa_ce_discovery_cback(): event:0x%02X", event);
246
247 switch (event)
248 {
249 case NFA_DM_RF_DISC_START_EVT:
250 NFA_TRACE_DEBUG1 ("nfa_ce_handle_disc_start (status=0x%x)", p_data->start);
251 break;
252
253 case NFA_DM_RF_DISC_ACTIVATED_EVT:
254 ce_msg.activate_ntf.hdr.event = NFA_CE_ACTIVATE_NTF_EVT;
255 ce_msg.activate_ntf.p_activation_params = &p_data->activate;
256 nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
257 break;
258
259 case NFA_DM_RF_DISC_DEACTIVATED_EVT:
260 /* DM broadcasts deactivaiton event in listen sleep state, so check before processing */
261 if (nfa_ce_cb.flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
262 {
263 ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
264 ce_msg.hdr.layer_specific = p_data->deactivate.type;
265 nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
266 }
267 break;
268
269 default:
270 NFA_TRACE_ERROR0 ("Unexpected event");
271 break;
272 }
273 }
274
275 /*******************************************************************************
276 **
277 ** Function nfc_ce_t3t_set_listen_params
278 **
279 ** Description Set t3t listening parameters
280 **
281 ** Returns Nothing
282 **
283 *******************************************************************************/
nfc_ce_t3t_set_listen_params(void)284 void nfc_ce_t3t_set_listen_params (void)
285 {
286 UINT8 i;
287 tNFA_CE_CB *p_cb = &nfa_ce_cb;
288 UINT8 tlv[32], *p_params;
289 UINT8 tlv_size;
290 UINT16 t3t_flags2_mask = 0xFFFF; /* Mask of which T3T_IDs are disabled */
291 UINT8 t3t_idx = 0;
292
293 /* Point to start of tlv buffer */
294 p_params = tlv;
295
296 /* Set system code and NFCID2 */
297 for (i=0; i<NFA_CE_LISTEN_INFO_MAX; i++)
298 {
299 if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
300 (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
301 {
302 /* Set tag's system code and NFCID2 */
303 UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_ID1+t3t_idx); /* type */
304 UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_ID); /* length */
305 UINT16_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_system_code); /* System Code */
306 ARRAY_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_nfcid2, NCI_RF_F_UID_LEN);
307
308 /* Set mask for this ID */
309 t3t_flags2_mask &= ~((UINT16) (1<<t3t_idx));
310 t3t_idx++;
311 }
312 }
313
314 /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
315 t3t_flags2_mask = ~t3t_flags2_mask;
316
317 UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_FLAGS2); /* type */
318 UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
319 UINT16_TO_STREAM (p_params, t3t_flags2_mask); /* Mask of IDs to disable listening */
320
321 tlv_size = (UINT8) (p_params-tlv);
322 nfa_dm_check_set_config (tlv_size, (UINT8 *)tlv, FALSE);
323 }
324
325 /*******************************************************************************
326 **
327 ** Function nfa_ce_t3t_generate_rand_nfcid
328 **
329 ** Description Generate a random NFCID2 for Type-3 tag
330 **
331 ** Returns Nothing
332 **
333 *******************************************************************************/
nfa_ce_t3t_generate_rand_nfcid(UINT8 nfcid2[NCI_RF_F_UID_LEN])334 void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN])
335 {
336 UINT32 rand_seed = GKI_get_tick_count ();
337
338 /* For Type-3 tag, nfcid2 starts witn 02:fe */
339 nfcid2[0] = 0x02;
340 nfcid2[1] = 0xFE;
341
342 /* The remaining 6 bytes are random */
343 nfcid2[2] = (UINT8) (rand_seed & 0xFF);
344 nfcid2[3] = (UINT8) (rand_seed>>8 & 0xFF);
345 rand_seed>>=(rand_seed&3);
346 nfcid2[4] = (UINT8) (rand_seed & 0xFF);
347 nfcid2[5] = (UINT8) (rand_seed>>8 & 0xFF);
348 rand_seed>>=(rand_seed&3);
349 nfcid2[6] = (UINT8) (rand_seed & 0xFF);
350 nfcid2[7] = (UINT8) (rand_seed>>8 & 0xFF);
351 }
352
353 /*******************************************************************************
354 **
355 ** Function nfa_ce_start_listening
356 **
357 ** Description Start listening
358 **
359 ** Returns NFA_STATUS_OK if successful
360 **
361 *******************************************************************************/
nfa_ce_start_listening(void)362 tNFA_STATUS nfa_ce_start_listening (void)
363 {
364 tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
365 tNFA_CE_CB *p_cb = &nfa_ce_cb;
366 tNFA_HANDLE disc_handle;
367 UINT8 listen_info_idx;
368
369 /*************************************************************************/
370 /* Construct protocol preference list to listen for */
371
372 /* First, get protocol preference for active NDEF (if any) */
373 if ( (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
374 &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle == NFA_HANDLE_INVALID))
375 {
376 listen_mask = 0;
377
378 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_T3T)
379 {
380 /* set T3T config params */
381 nfc_ce_t3t_set_listen_params ();
382
383 listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
384 }
385
386 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
387 {
388 listen_mask |= nfa_ce_cb.isodep_disc_mask;
389 }
390
391 disc_handle = nfa_dm_add_rf_discover (listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_ce_discovery_cback);
392
393 if (disc_handle == NFA_HANDLE_INVALID)
394 return (NFA_STATUS_FAILED);
395 else
396 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = disc_handle;
397 }
398
399 /* Next, add protocols from non-NDEF, if any */
400 for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
401 {
402 /* add RF discovery to DM only if it is not added yet */
403 if ( (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
404 &&(p_cb->listen_info[listen_info_idx].rf_disc_handle == NFA_HANDLE_INVALID))
405 {
406 if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
407 {
408 /* set T3T config params */
409 nfc_ce_t3t_set_listen_params ();
410
411 disc_handle = nfa_dm_add_rf_discover (NFA_DM_DISC_MASK_LF_T3T,
412 NFA_DM_DISC_HOST_ID_DH,
413 nfa_ce_discovery_cback);
414
415 if (disc_handle == NFA_HANDLE_INVALID)
416 return (NFA_STATUS_FAILED);
417 else
418 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
419 }
420 else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
421 {
422 disc_handle = nfa_dm_add_rf_discover (nfa_ce_cb.isodep_disc_mask,
423 NFA_DM_DISC_HOST_ID_DH,
424 nfa_ce_discovery_cback);
425
426 if (disc_handle == NFA_HANDLE_INVALID)
427 return (NFA_STATUS_FAILED);
428 else
429 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
430 }
431 #if (NFC_NFCEE_INCLUDED == TRUE)
432 else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
433 {
434 listen_mask = 0;
435 if (nfa_ee_is_active (p_cb->listen_info[listen_info_idx].ee_handle))
436 {
437 if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_A)
438 {
439 listen_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
440 }
441 if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B)
442 {
443 listen_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
444 }
445 if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F)
446 {
447 listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
448 }
449 if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
450 {
451 listen_mask |= NFA_DM_DISC_MASK_L_B_PRIME;
452 }
453 }
454
455 if (listen_mask)
456 {
457 /* Start listening for requested technologies */
458 /* register discovery callback to NFA DM */
459 disc_handle = nfa_dm_add_rf_discover (listen_mask,
460 (tNFA_DM_DISC_HOST_ID) (p_cb->listen_info[listen_info_idx].ee_handle &0x00FF),
461 nfa_ce_discovery_cback);
462
463 if (disc_handle == NFA_HANDLE_INVALID)
464 return (NFA_STATUS_FAILED);
465 else
466 {
467 p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
468 p_cb->listen_info[listen_info_idx].tech_proto_mask = listen_mask;
469 }
470 }
471 else
472 {
473 NFA_TRACE_ERROR1 ("UICC[0x%x] is not activated",
474 p_cb->listen_info[listen_info_idx].ee_handle);
475 }
476 }
477 #endif
478 }
479 }
480
481 return NFA_STATUS_OK;
482 }
483
484 /*******************************************************************************
485 **
486 ** Function nfa_ce_restart_listen_check
487 **
488 ** Description Called on deactivation. Check if any active listen_info entries to listen for
489 **
490 ** Returns TRUE if listening is restarted.
491 ** FALSE if listening not restarted
492 **
493 *******************************************************************************/
nfa_ce_restart_listen_check(void)494 BOOLEAN nfa_ce_restart_listen_check (void)
495 {
496 tNFA_CE_CB *p_cb = &nfa_ce_cb;
497 UINT8 listen_info_idx;
498
499 /* Check if any active entries in listen_info table */
500 for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
501 {
502 if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
503 break;
504 }
505
506 /* Restart listening if there are any active listen_info entries */
507 if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
508 {
509 /* restart listening */
510 nfa_ce_start_listening ();
511 }
512 else
513 {
514 /* No active listen_info entries */
515 return FALSE;
516 }
517
518 return TRUE;
519 }
520
521 /*******************************************************************************
522 **
523 ** Function nfa_ce_remove_listen_info_entry
524 **
525 ** Description Remove entry from listen_info table. (when API deregister is called or listen_start failed)
526 **
527 **
528 ** Returns Nothing
529 **
530 *******************************************************************************/
nfa_ce_remove_listen_info_entry(UINT8 listen_info_idx,BOOLEAN notify_app)531 void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app)
532 {
533 tNFA_CE_CB *p_cb = &nfa_ce_cb;
534 tNFA_CONN_EVT_DATA conn_evt;
535
536 NFA_TRACE_DEBUG1 ("NFA_CE: removing listen_info entry %i", listen_info_idx);
537
538 /* Notify app that listening has stopped if requested (for API deregister) */
539 /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT failure */
540 if (notify_app)
541 {
542 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
543 {
544 conn_evt.status = NFA_STATUS_OK;
545 (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
546 }
547 #if (NFC_NFCEE_INCLUDED == TRUE)
548 else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
549 {
550 conn_evt.status = NFA_STATUS_OK;
551 (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
552 }
553 #endif
554 else
555 {
556 conn_evt.ce_deregistered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
557 (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_DEREGISTERED_EVT, &conn_evt);
558 }
559 }
560
561
562 /* Handle NDEF stopping */
563 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
564 {
565 /* clear NDEF contents */
566 CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
567 CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
568
569 if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
570 {
571 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
572
573 /* clear T3T Flags for NDEF */
574 nfc_ce_t3t_set_listen_params ();
575 }
576
577 /* Free scratch buffer for this NDEF, if one was allocated */
578 nfa_ce_free_scratch_buf ();
579 }
580 /* If stopping listening Felica system code, then clear T3T Flags for this */
581 else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
582 {
583 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
584
585 /* clear T3T Flags for registered Felica system code */
586 nfc_ce_t3t_set_listen_params ();
587 }
588 /* If stopping listening T4T AID, then deregister this AID from CE_T4T */
589 else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
590 {
591 /* Free t4t_aid_cback used by this AID */
592 CE_T4tDeregisterAID (p_cb->listen_info[listen_info_idx].t4t_aid_handle);
593 }
594
595 if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID )
596 {
597 nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
598 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
599 }
600
601 /* Remove entry from listen_info table */
602 p_cb->listen_info[listen_info_idx].flags = 0;
603 }
604
605 /*******************************************************************************
606 **
607 ** Function nfa_ce_free_scratch_buf
608 **
609 ** Description free scratch buffer (if one is allocated)
610 **
611 ** Returns nothing
612 **
613 *******************************************************************************/
nfa_ce_free_scratch_buf(void)614 void nfa_ce_free_scratch_buf (void)
615 {
616 tNFA_CE_CB *p_cb = &nfa_ce_cb;
617 if (p_cb->p_scratch_buf)
618 {
619 nfa_mem_co_free (p_cb->p_scratch_buf);
620 p_cb->p_scratch_buf = NULL;
621 }
622 }
623
624 /*******************************************************************************
625 **
626 ** Function nfa_ce_realloc_scratch_buffer
627 **
628 ** Description Set scratch buffer if necessary (for writable NDEF messages)
629 **
630 ** Returns NFA_STATUS_OK if successful
631 **
632 *******************************************************************************/
nfa_ce_realloc_scratch_buffer(void)633 tNFA_STATUS nfa_ce_realloc_scratch_buffer (void)
634 {
635 tNFA_STATUS result = NFA_STATUS_OK;
636
637 /* If current NDEF message is read-only, then we do not need a scratch buffer */
638 if (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF)
639 {
640 /* Free existing scratch buffer, if one was allocated */
641 nfa_ce_free_scratch_buf ();
642 }
643 else
644 {
645 /* If no scratch buffer allocated yet, or if current scratch buffer size is different from current ndef size, */
646 /* then allocate a new scratch buffer. */
647 if ((nfa_ce_cb.p_scratch_buf == NULL) ||
648 (nfa_ce_cb.scratch_buf_size != nfa_ce_cb.ndef_max_size))
649 {
650 /* Free existing scratch buffer, if one was allocated */
651 nfa_ce_free_scratch_buf ();
652
653 if ((nfa_ce_cb.p_scratch_buf = (UINT8 *) nfa_mem_co_alloc (nfa_ce_cb.ndef_max_size)) != NULL)
654 {
655 nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
656 }
657 else
658 {
659 NFA_TRACE_ERROR1 ("Unable to allocate scratch buffer for writable NDEF message (%i bytes)", nfa_ce_cb.ndef_max_size);
660 result=NFA_STATUS_FAILED;
661 }
662 }
663 }
664
665 return (result);
666 }
667
668 /*******************************************************************************
669 **
670 ** Function nfa_ce_set_content
671 **
672 ** Description Set NDEF contents
673 **
674 ** Returns void
675 **
676 *******************************************************************************/
nfa_ce_set_content(void)677 tNFC_STATUS nfa_ce_set_content (void)
678 {
679 tNFC_STATUS status;
680 tNFA_CE_CB *p_cb = &nfa_ce_cb;
681 tNFA_PROTOCOL_MASK ndef_protocol_mask;
682 BOOLEAN readonly;
683
684 /* Check if listening for NDEF */
685 if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE))
686 {
687 /* Not listening for NDEF */
688 return (NFA_STATUS_OK);
689 }
690
691 NFA_TRACE_DEBUG0 ("Setting NDEF contents");
692
693 readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF) ? TRUE : FALSE;
694 ndef_protocol_mask = p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
695
696 /* Allocate a scratch buffer if needed (for handling write-requests) */
697 if ((status = nfa_ce_realloc_scratch_buffer ()) == NFA_STATUS_OK)
698 {
699 if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) && (status == NFA_STATUS_OK))
700 {
701 /* Type3Tag - NFC-F */
702 status = CE_T3tSetLocalNDEFMsg (readonly,
703 p_cb->ndef_max_size,
704 p_cb->ndef_cur_size,
705 p_cb->p_ndef_data,
706 p_cb->p_scratch_buf);
707 }
708
709 if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) && (status == NFA_STATUS_OK))
710 {
711 /* ISODEP/4A,4B- NFC-A or NFC-B */
712 status = CE_T4tSetLocalNDEFMsg (readonly,
713 p_cb->ndef_max_size,
714 p_cb->ndef_cur_size,
715 p_cb->p_ndef_data,
716 p_cb->p_scratch_buf);
717 }
718 }
719
720 if (status != NFA_STATUS_OK)
721 {
722 /* clear NDEF contents */
723 CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
724 CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
725
726 NFA_TRACE_ERROR1 ("Unable to set contents (error %02x)", status);
727 }
728
729 return (status);
730 }
731
732
733 /*******************************************************************************
734 **
735 ** Function nfa_ce_activate_ntf
736 **
737 ** Description Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
738 **
739 ** - Find the listen_info entry assocated with this activation
740 ** - get the app callback that registered for this listen
741 ** - call CE_SetActivatedTagType with activation parameters
742 **
743 ** Returns TRUE (message buffer to be freed by caller)
744 **
745 *******************************************************************************/
nfa_ce_activate_ntf(tNFA_CE_MSG * p_ce_msg)746 BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg)
747 {
748 tNFC_ACTIVATE_DEVT *p_activation_params = p_ce_msg->activate_ntf.p_activation_params;
749 tNFA_CE_CB *p_cb = &nfa_ce_cb;
750 tNFA_CONN_EVT_DATA conn_evt;
751 tCE_CBACK *p_ce_cback = NULL;
752 UINT16 t3t_system_code = 0xFFFF;
753 UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
754 UINT8 *p_nfcid2 = NULL;
755 UINT8 i;
756 BOOLEAN t4t_activate_pending = FALSE;
757
758 NFA_TRACE_DEBUG1 ("nfa_ce_activate_ntf () protocol=%d", p_ce_msg->activate_ntf.p_activation_params->protocol);
759
760 /* Tag is in listen active state */
761 p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
762
763 /* Store activation parameters */
764 memcpy (&p_cb->activation_params, p_activation_params, sizeof (tNFC_ACTIVATE_DEVT));
765
766 /* Find the listen_info entry corresponding to this activation */
767 if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
768 {
769 /* Look for T3T entries in listen_info table that match activated system code and NFCID2 */
770 for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
771 {
772 /* Look for entries with NFA_PROTOCOL_MASK_T3T */
773 if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
774 {
775 if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
776 {
777 /* Check if system_code and nfcid2 that matches activation params */
778 p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
779 t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
780
781 /* Compare NFCID2 (note: NFCC currently does not return system code in activation parameters) */
782 if ((memcmp (p_nfcid2, p_cb->activation_params.rf_tech_param.param.lf.nfcid2, NCI_RF_F_UID_LEN)==0)
783 /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */)
784 {
785 /* Found listen_info corresponding to this activation */
786 break;
787 }
788 }
789
790 /* Check if entry is for T3T UICC */
791 if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC) &&
792 (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F))
793 {
794 break;
795 }
796 }
797 }
798
799 p_ce_cback = nfa_ce_handle_t3t_evt;
800 }
801 else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
802 {
803 p_ce_cback = nfa_ce_handle_t4t_evt;
804
805 /* For T4T, we do not know which AID will be selected yet */
806
807
808 /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag */
809 for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
810 {
811 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
812 {
813 if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
814 {
815 /* Found listen_info table entry for T4T raw listen */
816 p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
817
818 /* If entry if for NDEF, select it, so application gets nofitifed of ACTIVATE_EVT now */
819 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
820 {
821 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
822 }
823
824 t4t_activate_pending = TRUE;
825 }
826
827 #if (NFC_NFCEE_INCLUDED == TRUE)
828 /* Check if entry is for ISO_DEP UICC */
829 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
830 {
831 if ( ( (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A)
832 &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) )
833 ||
834 ( (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B)
835 &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) ) )
836 {
837 listen_info_idx = i;
838 }
839 }
840 #endif
841 }
842 }
843
844 /* If listening for ISO_DEP, but not NDEF nor UICC, then notify CE module now and wait for reader/writer to SELECT an AID */
845 if (t4t_activate_pending && (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID))
846 {
847 CE_SetActivatedTagType (&p_cb->activation_params, 0, p_ce_cback);
848 return TRUE;
849 }
850 }
851 else if (p_cb->activation_params.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
852 {
853 /* search any entry listening UICC */
854 for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
855 {
856 if ( (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
857 &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC))
858 {
859 listen_info_idx = i;
860 break;
861 }
862 }
863 }
864
865 /* Check if valid listen_info entry was found */
866 if ( (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
867 ||((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) && !(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)))
868 {
869 NFA_TRACE_DEBUG1 ("No listen_info found for this activation. listen_info_idx=%d", listen_info_idx);
870 return (TRUE);
871 }
872
873 p_cb->listen_info[listen_info_idx].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
874
875 /* Get CONN_CBACK for this activation */
876 p_cb->p_active_conn_cback = p_cb->listen_info[listen_info_idx].p_conn_cback;
877 p_cb->idx_cur_active = listen_info_idx;
878
879 if ( (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
880 ||(p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_UICC))
881 {
882 memcpy (&(conn_evt.activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
883
884 (*p_cb->p_active_conn_cback) (NFA_ACTIVATED_EVT, &conn_evt);
885 }
886 else
887 {
888 conn_evt.ce_activated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
889 memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
890 conn_evt.ce_activated.status = NFA_STATUS_OK;
891
892 (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
893 }
894
895 /* we don't need any CE subsystem in case of NFCEE direct RF interface */
896 if (p_ce_cback)
897 {
898 /* Notify CE subsystem */
899 CE_SetActivatedTagType (&p_cb->activation_params, t3t_system_code, p_ce_cback);
900 }
901 return TRUE;
902 }
903
904 /*******************************************************************************
905 **
906 ** Function nfa_ce_deactivate_ntf
907 **
908 ** Description Action when deactivate occurs. (NFA_CE_DEACTIVATE_NTF_EVT)
909 **
910 ** - If deactivate due to API deregister, then remove its entry from
911 ** listen_info table
912 **
913 ** - If NDEF was modified while activated, then restore
914 ** original NDEF contents
915 **
916 ** - Restart listening (if any active entries in listen table)
917 **
918 ** Returns TRUE (message buffer to be freed by caller)
919 **
920 *******************************************************************************/
nfa_ce_deactivate_ntf(tNFA_CE_MSG * p_ce_msg)921 BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg)
922 {
923 tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE) p_ce_msg->hdr.layer_specific;
924 tNFA_CE_CB *p_cb = &nfa_ce_cb;
925 tNFA_CONN_EVT_DATA conn_evt;
926 UINT8 i;
927
928 NFA_TRACE_DEBUG1 ("nfa_ce_deactivate_ntf () deact_type=%d", deact_type);
929
930 /* Check if deactivating to SLEEP mode */
931 if ( (deact_type == NFC_DEACTIVATE_TYPE_SLEEP)
932 ||(deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF) )
933 {
934 /* notify deactivated as sleep and wait for reactivation or deactivation to idle */
935 conn_evt.deactivated.type = deact_type;
936
937 /* if T4T AID application has not been selected then p_active_conn_cback could be NULL */
938 if (p_cb->p_active_conn_cback)
939 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
940
941 return TRUE;
942 }
943 else
944 {
945 deact_type = NFC_DEACTIVATE_TYPE_IDLE;
946 }
947
948 /* Tag is in idle state */
949 p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
950
951 /* First, notify app of deactivation */
952 for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
953 {
954 if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
955 {
956 if ( (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
957 &&(i == p_cb->idx_cur_active) )
958 {
959 conn_evt.deactivated.type = deact_type;
960 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
961 }
962 else if ( (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
963 &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP))
964 {
965 /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
966 if (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND))
967 {
968 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
969 {
970 conn_evt.deactivated.type = deact_type;
971 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
972 }
973 else
974 {
975 conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
976 conn_evt.ce_deactivated.type = deact_type;
977 (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
978 }
979 }
980 }
981 else if ( (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
982 &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
983 {
984 if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
985 {
986 conn_evt.deactivated.type = deact_type;
987 (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
988 }
989 else
990 {
991 conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
992 conn_evt.ce_deactivated.type = deact_type;
993 (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
994 }
995 }
996 }
997 }
998
999 /* Check if app initiated the deactivation (due to API deregister). If so, remove entry from listen_info table. */
1000 if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION)
1001 {
1002 p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1003 nfa_ce_remove_listen_info_entry (p_cb->idx_cur_active, TRUE);
1004 }
1005
1006 p_cb->p_active_conn_cback = NULL;
1007 p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_INVALID;
1008
1009 /* Restart listening (if any listen_info entries are still active) */
1010 nfa_ce_restart_listen_check ();
1011
1012 return TRUE;
1013 }
1014
1015 /*******************************************************************************
1016 **
1017 ** Function nfa_ce_disable_local_tag
1018 **
1019 ** Description Disable local NDEF tag
1020 ** - clean up control block
1021 ** - remove NDEF discovery configuration
1022 **
1023 ** Returns Nothing
1024 **
1025 *******************************************************************************/
nfa_ce_disable_local_tag(void)1026 void nfa_ce_disable_local_tag (void)
1027 {
1028 tNFA_CE_CB *p_cb = &nfa_ce_cb;
1029 tNFA_CONN_EVT_DATA evt_data;
1030
1031 NFA_TRACE_DEBUG0 ("Disabling local NDEF tag");
1032
1033 /* If local NDEF tag is in use, then disable it */
1034 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1035 {
1036 /* NDEF Tag is in not idle state */
1037 if ( (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1038 &&(p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) )
1039 {
1040 /* wait for deactivation */
1041 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1042 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1043 }
1044 else
1045 {
1046 /* Notify DM to stop listening for ndef */
1047 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1048 {
1049 nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1050 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1051 }
1052 nfa_ce_remove_listen_info_entry (NFA_CE_LISTEN_INFO_IDX_NDEF, TRUE);
1053 }
1054 }
1055 else
1056 {
1057 /* Notify application */
1058 evt_data.status = NFA_STATUS_OK;
1059 nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
1060 }
1061 }
1062
1063 /*******************************************************************************
1064 **
1065 ** Function nfa_ce_api_cfg_local_tag
1066 **
1067 ** Description Configure local NDEF tag
1068 ** - store ndef attributes in to control block
1069 ** - update discovery configuration
1070 **
1071 ** Returns TRUE (message buffer to be freed by caller)
1072 **
1073 *******************************************************************************/
nfa_ce_api_cfg_local_tag(tNFA_CE_MSG * p_ce_msg)1074 BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg)
1075 {
1076 tNFA_CE_CB *p_cb = &nfa_ce_cb;
1077 tNFA_CONN_EVT_DATA conn_evt;
1078
1079 /* Check if disabling local tag */
1080 if (p_ce_msg->local_tag.protocol_mask == 0)
1081 {
1082 nfa_ce_disable_local_tag ();
1083 return TRUE;
1084 }
1085
1086 NFA_TRACE_DEBUG5 ("Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, max_size=%i, readonly=%i",
1087 p_ce_msg->local_tag.protocol_mask,
1088 p_ce_msg->local_tag.ndef_cur_size,
1089 p_ce_msg->local_tag.ndef_max_size,
1090 p_ce_msg->local_tag.read_only,
1091 p_ce_msg->local_tag.uid_len);
1092
1093 /* If local tag was already set, then check if NFA_CeConfigureLocalTag called to change protocol mask */
1094 if ( (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
1095 &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
1096 &&((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1097 != (p_ce_msg->local_tag.protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))) )
1098 {
1099 /* Listening for different tag protocols. Stop discovery */
1100 nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
1101 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
1102
1103 /* clear NDEF contents */
1104 CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1105 CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
1106 }
1107
1108 /* Store NDEF info to control block */
1109 p_cb->p_ndef_data = p_ce_msg->local_tag.p_ndef_data;
1110 p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
1111 p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
1112
1113 /* Fill in LISTEN_INFO entry for NDEF */
1114 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags = NFA_CE_LISTEN_INFO_IN_USE;
1115 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask = p_ce_msg->local_tag.protocol_mask;
1116 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback = nfa_dm_conn_cback_event_notify;
1117 if (p_ce_msg->local_tag.read_only)
1118 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |= NFC_CE_LISTEN_INFO_READONLY_NDEF;
1119 p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code = T3T_SYSTEM_CODE_NDEF;
1120
1121 /* Set NDEF contents */
1122 conn_evt.status = NFA_STATUS_FAILED;
1123
1124 if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
1125 {
1126 /* Ok to set contents now */
1127 if (nfa_ce_set_content () != NFA_STATUS_OK)
1128 {
1129 NFA_TRACE_ERROR0 ("nfa_ce_api_cfg_local_tag: could not set contents");
1130 nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1131 return TRUE;
1132 }
1133
1134 /* Start listening and notify app of status */
1135 conn_evt.status = nfa_ce_start_listening ();
1136 nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
1137 }
1138
1139 return TRUE;
1140 }
1141
1142 /*******************************************************************************
1143 **
1144 ** Function nfa_ce_api_reg_listen
1145 **
1146 ** Description Register listen params for Felica system code, T4T AID,
1147 ** or UICC
1148 **
1149 ** Returns TRUE (message buffer to be freed by caller)
1150 **
1151 *******************************************************************************/
nfa_ce_api_reg_listen(tNFA_CE_MSG * p_ce_msg)1152 BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg)
1153 {
1154 tNFA_CE_CB *p_cb = &nfa_ce_cb;
1155 tNFA_CONN_EVT_DATA conn_evt;
1156 UINT8 i;
1157 UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
1158
1159 NFA_TRACE_DEBUG1 ("Registering UICC/Felica/Type-4 tag listener. Type=%i", p_ce_msg->reg_listen.listen_type);
1160
1161 /* Look for available entry in listen_info table */
1162 /* - If registering UICC listen, make sure there isn't another entry for the ee_handle */
1163 /* - Skip over entry 0 (reserved for local NDEF tag) */
1164 for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
1165 {
1166 if ( (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1167 &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
1168 &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
1169 &&(p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle) )
1170 {
1171
1172 NFA_TRACE_ERROR1 ("UICC (0x%x) listening already specified", p_ce_msg->reg_listen.ee_handle);
1173 conn_evt.status = NFA_STATUS_FAILED;
1174 nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1175 return TRUE;
1176 }
1177 /* If this is a free entry, and we haven't found one yet, remember it */
1178 else if ( (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE))
1179 &&(listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) )
1180 {
1181 listen_info_idx = i;
1182 }
1183 }
1184
1185 /* Add new entry to listen_info table */
1186 if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
1187 {
1188 NFA_TRACE_ERROR1 ("Maximum listen callbacks exceeded (%i)", NFA_CE_LISTEN_INFO_MAX);
1189
1190 if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1191 {
1192 conn_evt.status = NFA_STATUS_FAILED;
1193 nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1194 }
1195 else
1196 {
1197 /* Notify application */
1198 conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1199 conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1200 (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1201 }
1202 return TRUE;
1203 }
1204 else
1205 {
1206 NFA_TRACE_DEBUG1 ("NFA_CE: adding listen_info entry %i", listen_info_idx);
1207
1208 /* Store common parameters */
1209 /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
1210 /* (LISTEN_START_EVT will be notified when discovery successfully starts */
1211 p_cb->listen_info[listen_info_idx].flags = NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
1212 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1213 p_cb->listen_info[listen_info_idx].protocol_mask = 0;
1214
1215 /* Store type-specific parameters */
1216 switch (p_ce_msg->reg_listen.listen_type)
1217 {
1218 case NFA_CE_REG_TYPE_ISO_DEP:
1219 p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_ISO_DEP;
1220 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
1221 p_cb->listen_info[listen_info_idx].p_conn_cback =p_ce_msg->reg_listen.p_conn_cback;
1222
1223 /* Register this AID with CE_T4T */
1224 if ((p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID (p_ce_msg->reg_listen.aid_len,
1225 p_ce_msg->reg_listen.aid,
1226 nfa_ce_handle_t4t_aid_evt)) == 0xFF)
1227 {
1228 NFA_TRACE_ERROR0 ("Unable to register AID");
1229 p_cb->listen_info[listen_info_idx].flags = 0;
1230
1231 /* Notify application */
1232 conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
1233 conn_evt.ce_registered.status = NFA_STATUS_FAILED;
1234 (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1235
1236 return TRUE;
1237 }
1238 break;
1239
1240 case NFA_CE_REG_TYPE_FELICA:
1241 p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_T3T;
1242 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
1243 p_cb->listen_info[listen_info_idx].p_conn_cback = p_ce_msg->reg_listen.p_conn_cback;
1244
1245 /* Store system code and nfcid2 */
1246 p_cb->listen_info[listen_info_idx].t3t_system_code = p_ce_msg->reg_listen.system_code;
1247 memcpy (p_cb->listen_info[listen_info_idx].t3t_nfcid2, p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
1248 break;
1249
1250 #if (NFC_NFCEE_INCLUDED == TRUE)
1251 case NFA_CE_REG_TYPE_UICC:
1252 p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
1253 p_cb->listen_info[listen_info_idx].p_conn_cback = &nfa_dm_conn_cback_event_notify;
1254
1255 /* Store EE handle and Tech */
1256 p_cb->listen_info[listen_info_idx].ee_handle = p_ce_msg->reg_listen.ee_handle;
1257 p_cb->listen_info[listen_info_idx].tech_mask = p_ce_msg->reg_listen.tech_mask;
1258 break;
1259 #endif
1260 }
1261 }
1262
1263 /* Start listening */
1264 if ((conn_evt.status = nfa_ce_start_listening ()) != NFA_STATUS_OK)
1265 {
1266 NFA_TRACE_ERROR0 ("nfa_ce_api_reg_listen: unable to register new listen params with DM");
1267 p_cb->listen_info[listen_info_idx].flags = 0;
1268 }
1269
1270 /* Nofitify app of status */
1271 if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
1272 {
1273 (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1274 }
1275 else
1276 {
1277 conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
1278 NFA_TRACE_DEBUG1 ("nfa_ce_api_reg_listen: registered handle 0x%04X", conn_evt.ce_registered.handle);
1279 (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
1280 }
1281
1282 return TRUE;
1283 }
1284
1285 /*******************************************************************************
1286 **
1287 ** Function nfa_ce_api_dereg_listen
1288 **
1289 ** Description Deregister listen params
1290 **
1291 ** Returns TRUE (message buffer to be freed by caller)
1292 **
1293 *******************************************************************************/
nfa_ce_api_dereg_listen(tNFA_CE_MSG * p_ce_msg)1294 BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg)
1295 {
1296 tNFA_CE_CB *p_cb = &nfa_ce_cb;
1297 UINT8 listen_info_idx;
1298 tNFA_CONN_EVT_DATA conn_evt;
1299
1300 #if (NFC_NFCEE_INCLUDED == TRUE)
1301 /* Check if deregistering UICC , or virtual secure element listen */
1302 if (p_ce_msg->dereg_listen.listen_info == NFA_CE_LISTEN_INFO_UICC)
1303 {
1304 /* Deregistering UICC listen. Look for listen_info for this UICC ee handle */
1305 for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
1306 {
1307 if ( (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
1308 &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
1309 &&(p_cb->listen_info[listen_info_idx].ee_handle == p_ce_msg->dereg_listen.handle) )
1310 {
1311 /* UICC is in not idle state */
1312 if ( (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1313 &&(p_cb->idx_cur_active == listen_info_idx) )
1314 {
1315 /* wait for deactivation */
1316 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1317 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1318 }
1319 else
1320 {
1321 /* Stop listening */
1322 if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1323 {
1324 nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1325 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1326 }
1327
1328 /* Remove entry and notify application */
1329 nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1330 }
1331 break;
1332 }
1333 }
1334
1335 if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX)
1336 {
1337 NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
1338 conn_evt.status = NFA_STATUS_INVALID_PARAM;
1339 nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
1340 }
1341 }
1342 else
1343 #endif
1344 {
1345 /* Deregistering virtual secure element listen */
1346 listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
1347
1348 if ( (listen_info_idx < NFA_CE_LISTEN_INFO_MAX)
1349 &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE))
1350 {
1351 /* virtual secure element is in not idle state */
1352 if ( (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
1353 &&(p_cb->idx_cur_active == listen_info_idx) )
1354 {
1355 /* wait for deactivation */
1356 p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
1357 nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1358 }
1359 else
1360 {
1361 /* Stop listening */
1362 if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
1363 {
1364 nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
1365 p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
1366 }
1367
1368 /* Remove entry and notify application */
1369 nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
1370 }
1371 }
1372 else
1373 {
1374 NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for Felica/T4tAID");
1375 conn_evt.status = NFA_STATUS_INVALID_PARAM;
1376 nfa_dm_conn_cback_event_notify (NFA_CE_DEREGISTERED_EVT, &conn_evt);
1377 }
1378 }
1379
1380 return TRUE;
1381 }
1382
1383 /*******************************************************************************
1384 **
1385 ** Function nfa_ce_api_cfg_isodep_tech
1386 **
1387 ** Description Configure the technologies (NFC-A and/or NFC-B) to listen for
1388 ** ISO-DEP
1389 **
1390 ** Returns TRUE (message buffer to be freed by caller)
1391 **
1392 *******************************************************************************/
nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG * p_ce_msg)1393 BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg)
1394 {
1395 nfa_ce_cb.isodep_disc_mask = 0;
1396 if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
1397 nfa_ce_cb.isodep_disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
1398
1399 if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
1400 nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
1401 return TRUE;
1402 }
1403
1404