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