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