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