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