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