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