• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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