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