nfa_dm_discover.c revision 6c6e360bd24d846d6e928d657a9c69163e170fa1
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-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 for device manager discovery
22 *  function.
23 *
24 ******************************************************************************/
25#include <string.h>
26#include "nci_hmsgs.h"
27#include "nfa_api.h"
28#include "nfa_dm_int.h"
29#include "nfa_p2p_int.h"
30#include "nfa_sys.h"
31#include "nfa_sys_int.h"
32#if (NFC_NFCEE_INCLUDED == TRUE)
33#include "nfa_ee_api.h"
34#include "nfa_ee_int.h"
35#endif
36#include "nfa_rw_int.h"
37
38#include "nfc_int.h"
39/*
40**  static functions
41*/
42
43static uint8_t nfa_dm_get_rf_discover_config(
44    tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
45    tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params);
46static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
47    tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
48static void nfa_dm_set_rf_listen_mode_raw_config(
49    tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask);
50static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
51    tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol);
52static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data);
53static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data);
54static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
55                                            tNFC_DISCOVER* p_data);
56static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
57                                   tNFC_CONN* p_data);
58static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle);
59static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status);
60
61#if (BT_TRACE_VERBOSE == TRUE)
62static char* nfa_dm_disc_state_2_str(uint8_t state);
63static char* nfa_dm_disc_event_2_str(uint8_t event);
64#endif
65
66typedef struct nfa_dm_p2p_prio_logic {
67  bool isodep_detected;      /* flag to check if ISO-DEP is detected */
68  bool timer_expired;        /* flag to check whether timer is expired */
69  TIMER_LIST_ENT timer_list; /*timer structure pointer */
70  uint8_t first_tech_mode;
71} nfa_dm_p2p_prio_logic_t;
72
73static nfa_dm_p2p_prio_logic_t p2p_prio_logic_data;
74
75static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol);
76
77/*******************************************************************************
78**
79** Function         nfa_dm_get_rf_discover_config
80**
81** Description      Build RF discovery configurations from
82**                  tNFA_DM_DISC_TECH_PROTO_MASK
83**
84** Returns          number of RF discovery configurations
85**
86*******************************************************************************/
87static uint8_t nfa_dm_get_rf_discover_config(
88    tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
89    tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params) {
90  uint8_t num_params = 0;
91
92  if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED) {
93    NFA_TRACE_DEBUG1(
94        "nfa_dm_get_rf_discover_config () listen disabled, rm listen from 0x%x",
95        dm_disc_mask);
96    dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
97  }
98  if (nfa_dm_is_p2p_paused()) {
99    dm_disc_mask &= ~NFA_DM_DISC_MASK_NFC_DEP;
100  }
101
102  /* Check polling A */
103  if (dm_disc_mask &
104      (NFA_DM_DISC_MASK_PA_T1T | NFA_DM_DISC_MASK_PA_T2T |
105       NFA_DM_DISC_MASK_PA_ISO_DEP | NFA_DM_DISC_MASK_PA_NFC_DEP |
106       NFA_DM_DISC_MASK_P_LEGACY)) {
107    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A;
108    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pa;
109    num_params++;
110
111    if (num_params >= max_params) return num_params;
112  }
113
114  /* Check polling B */
115  if (dm_disc_mask & NFA_DM_DISC_MASK_PB_ISO_DEP) {
116    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B;
117    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pb;
118    num_params++;
119
120    if (num_params >= max_params) return num_params;
121  }
122
123  /* Check polling F */
124  if (dm_disc_mask & (NFA_DM_DISC_MASK_PF_T3T | NFA_DM_DISC_MASK_PF_NFC_DEP)) {
125    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F;
126    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pf;
127    num_params++;
128
129    if (num_params >= max_params) return num_params;
130  }
131  if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
132    /* Check polling Active mode  */
133    if (dm_disc_mask & NFA_DM_DISC_MASK_PACM_NFC_DEP) {
134      disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_ACTIVE;
135      disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pacm;
136      num_params++;
137
138      if (num_params >= max_params) return num_params;
139    }
140  } else {
141    /* Check polling A Active mode  */
142    if (dm_disc_mask & NFA_DM_DISC_MASK_PAA_NFC_DEP) {
143      disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A_ACTIVE;
144      disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->paa;
145      num_params++;
146
147      if (num_params >= max_params) return num_params;
148    }
149
150    /* Check polling F Active mode  */
151    if (dm_disc_mask & NFA_DM_DISC_MASK_PFA_NFC_DEP) {
152      disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F_ACTIVE;
153      disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pfa;
154      num_params++;
155
156      if (num_params >= max_params) return num_params;
157    }
158  }
159  /* Check listening A */
160  if (dm_disc_mask &
161      (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
162       NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) {
163    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A;
164    disc_params[num_params].frequency = 1;
165    num_params++;
166
167    if (num_params >= max_params) return num_params;
168  }
169
170  /* Check listening B */
171  if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
172    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B;
173    disc_params[num_params].frequency = 1;
174    num_params++;
175
176    if (num_params >= max_params) return num_params;
177  }
178
179  /* Check listening F */
180  if (dm_disc_mask & (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP)) {
181    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F;
182    disc_params[num_params].frequency = 1;
183    num_params++;
184
185    if (num_params >= max_params) return num_params;
186  }
187  if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
188    /* Check polling Active mode  */
189    if (dm_disc_mask & NFA_DM_DISC_MASK_LACM_NFC_DEP) {
190      disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ACTIVE;
191      disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pacm;
192      num_params++;
193      if (num_params >= max_params) return num_params;
194    }
195  } else {
196    /* Check listening A Active mode */
197    if (dm_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP) {
198      disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE;
199      disc_params[num_params].frequency = 1;
200      num_params++;
201
202      if (num_params >= max_params) return num_params;
203    }
204
205    /* Check listening F Active mode */
206    if (dm_disc_mask & NFA_DM_DISC_MASK_LFA_NFC_DEP) {
207      disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE;
208      disc_params[num_params].frequency = 1;
209      num_params++;
210
211      if (num_params >= max_params) return num_params;
212    }
213  }
214
215  /* Check polling ISO 15693 */
216  if (dm_disc_mask & NFA_DM_DISC_MASK_P_T5T) {
217    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_V;
218    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pi93;
219    num_params++;
220
221    if (num_params >= max_params) return num_params;
222  }
223
224  /* Check polling B' */
225  if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME) {
226    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
227    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pbp;
228    num_params++;
229
230    if (num_params >= max_params) return num_params;
231  }
232
233  /* Check polling KOVIO */
234  if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO) {
235    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_KOVIO;
236    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pk;
237    num_params++;
238
239    if (num_params >= max_params) return num_params;
240  }
241
242  /* Check listening ISO 15693 */
243  if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693) {
244    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
245    disc_params[num_params].frequency = 1;
246    num_params++;
247
248    if (num_params >= max_params) return num_params;
249  }
250
251  /* Check listening B' */
252  if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME) {
253    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
254    disc_params[num_params].frequency = 1;
255    num_params++;
256
257    if (num_params >= max_params) return num_params;
258  }
259
260  return num_params;
261}
262
263/*******************************************************************************
264**
265** Function         nfa_dm_set_rf_listen_mode_config
266**
267** Description      Update listening protocol to NFCC
268**
269** Returns          NFA_STATUS_OK if success
270**
271*******************************************************************************/
272static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
273    tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
274  uint8_t params[40], *p;
275  uint8_t platform = 0;
276  uint8_t sens_info = 0;
277
278  NFA_TRACE_DEBUG1(
279      "nfa_dm_set_rf_listen_mode_config () tech_proto_mask = 0x%08X",
280      tech_proto_mask);
281
282  /*
283  ** T1T listen     LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
284  ** T2T listen     LA_PROT 0x00
285  ** T3T listen     No bit for T3T in LF_PROT (CE T3T set listen parameters,
286  **                system code, NFCID2, etc.)
287  ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
288  ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
289  */
290
291  if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T) {
292    platform = NCI_PARAM_PLATFORM_T1T;
293  } else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T) {
294    /* platform = 0 and sens_info = 0 */
295  } else {
296    if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
297      sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
298    }
299
300    if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
301      sens_info |= NCI_PARAM_SEL_INFO_NFCDEP;
302    }
303  }
304
305  p = params;
306
307  /*
308  ** for Listen A
309  **
310  ** Set ATQA 0x0C00 for T1T listen
311  ** If the ATQA values are 0x0000, then the FW will use 0x0400
312  ** which works for ISODEP, T2T and NFCDEP.
313  */
314  if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
315      NFA_DM_DISC_HOST_ID_DH) {
316    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
317    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
318    UINT8_TO_STREAM(p, 0x04);
319    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
320    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
321    UINT8_TO_STREAM(p, platform);
322    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
323    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
324    UINT8_TO_STREAM(p, sens_info);
325  } else /* Let NFCC use UICC configuration by configuring with length = 0 */
326  {
327    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
328    UINT8_TO_STREAM(p, 0);
329    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
330    UINT8_TO_STREAM(p, 0);
331    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
332    UINT8_TO_STREAM(p, 0);
333    UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
334    UINT8_TO_STREAM(p, 0);
335    UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
336    UINT8_TO_STREAM(p, 0);
337  }
338
339  /* for Listen B */
340  if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
341      NFA_DM_DISC_HOST_ID_DH) {
342    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
343    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
344    if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
345      UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_ISO_DEP);
346    } else {
347      UINT8_TO_STREAM(p, 0x00);
348    }
349  } else /* Let NFCC use UICC configuration by configuring with length = 0 */
350  {
351    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
352    UINT8_TO_STREAM(p, 0);
353    UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
354    UINT8_TO_STREAM(p, 0);
355    UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
356    UINT8_TO_STREAM(p, 0);
357    UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
358    UINT8_TO_STREAM(p, 0);
359    UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
360    UINT8_TO_STREAM(p, 0);
361  }
362
363  /* for Listen F */
364  /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
365   * regardless of NFC-F tech routing */
366  UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
367  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
368  if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) &&
369      !nfa_dm_is_p2p_paused()) {
370    UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_NFC_DEP);
371  } else {
372    UINT8_TO_STREAM(p, 0x00);
373  }
374
375  if (p > params) {
376    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
377  }
378
379  return NFA_STATUS_OK;
380}
381
382/*******************************************************************************
383**
384** Function         nfa_dm_set_total_duration
385**
386** Description      Update total duration to NFCC
387**
388** Returns          void
389**
390*******************************************************************************/
391static void nfa_dm_set_total_duration(void) {
392  uint8_t params[10], *p;
393
394  NFA_TRACE_DEBUG0("nfa_dm_set_total_duration ()");
395
396  p = params;
397
398  /* for total duration */
399  UINT8_TO_STREAM(p, NFC_PMID_TOTAL_DURATION);
400  UINT8_TO_STREAM(p, NCI_PARAM_LEN_TOTAL_DURATION);
401  UINT16_TO_STREAM(p, nfa_dm_cb.disc_cb.disc_duration);
402
403  if (p > params) {
404    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
405  }
406}
407
408/*******************************************************************************
409**
410** Function         nfa_dm_set_rf_listen_mode_raw_config
411**
412** Description      Set raw listen parameters
413**
414** Returns          void
415**
416*******************************************************************************/
417static void nfa_dm_set_rf_listen_mode_raw_config(
418    tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask) {
419  tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
420  tNFA_LISTEN_CFG* p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
421  uint8_t params[250], *p, xx;
422
423  NFA_TRACE_DEBUG0("nfa_dm_set_rf_listen_mode_raw_config ()");
424
425  /*
426  ** Discovery Configuration Parameters for Listen A
427  */
428  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
429       NFA_DM_DISC_HOST_ID_DH) &&
430      (p_cfg->la_enable)) {
431    p = params;
432
433    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
434    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
435    UINT8_TO_STREAM(p, p_cfg->la_bit_frame_sdd);
436
437    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
438    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
439    UINT8_TO_STREAM(p, p_cfg->la_platform_config);
440
441    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
442    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
443    UINT8_TO_STREAM(p, p_cfg->la_sel_info);
444
445    if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T) {
446      disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
447    } else {
448      /* If T4T or NFCDEP */
449      if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP) {
450        disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
451      }
452
453      if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP) {
454        disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
455      }
456
457      /* If neither, T4T nor NFCDEP, then its T2T */
458      if (disc_mask == 0) {
459        disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
460      }
461    }
462
463    UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
464    UINT8_TO_STREAM(p, p_cfg->la_nfcid1_len);
465    ARRAY_TO_STREAM(p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
466
467    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
468  }
469
470  /*
471  ** Discovery Configuration Parameters for Listen B
472  */
473  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
474       NFA_DM_DISC_HOST_ID_DH) &&
475      (p_cfg->lb_enable)) {
476    p = params;
477
478    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
479    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
480    UINT8_TO_STREAM(p, p_cfg->lb_sensb_info);
481
482    UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
483    UINT8_TO_STREAM(p, p_cfg->lb_nfcid0_len);
484    ARRAY_TO_STREAM(p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
485
486    UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
487    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_APPDATA);
488    ARRAY_TO_STREAM(p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
489
490    UINT8_TO_STREAM(p, NFC_PMID_LB_SFGI);
491    UINT8_TO_STREAM(p, 1);
492    UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
493
494    UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
495    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_ADC_FO);
496    UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
497
498    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
499
500    if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP) {
501      disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
502    }
503  }
504
505  /*
506  ** Discovery Configuration Parameters for Listen F
507  */
508  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] ==
509       NFA_DM_DISC_HOST_ID_DH) &&
510      (p_cfg->lf_enable)) {
511    p = params;
512
513    UINT8_TO_STREAM(p, NFC_PMID_LF_CON_BITR_F);
514    UINT8_TO_STREAM(p, 1);
515    UINT8_TO_STREAM(p, p_cfg->lf_con_bitr_f);
516
517    UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
518    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
519    UINT8_TO_STREAM(p, p_cfg->lf_protocol_type);
520
521    UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_FLAGS2);
522    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
523    UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
524
525    /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be
526     * ignored */
527    for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++) {
528      if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000) {
529        UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_ID1 + xx);
530        UINT8_TO_STREAM(p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
531        ARRAY_TO_STREAM(p, p_cfg->lf_t3t_identifier[xx],
532                        NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
533      }
534    }
535
536    UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_PMM);
537    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_PMM);
538    ARRAY_TO_STREAM(p, p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
539
540    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
541
542    if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED) {
543      disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
544    }
545    if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP) {
546      disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
547    }
548  }
549
550  /*
551  ** Discovery Configuration Parameters for Listen ISO-DEP
552  */
553  if ((disc_mask &
554       (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)) &&
555      (p_cfg->li_enable)) {
556    p = params;
557
558    UINT8_TO_STREAM(p, NFC_PMID_FWI);
559    UINT8_TO_STREAM(p, NCI_PARAM_LEN_FWI);
560    UINT8_TO_STREAM(p, p_cfg->li_fwi);
561
562    if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
563      UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
564      UINT8_TO_STREAM(p, p_cfg->la_hist_bytes_len);
565      ARRAY_TO_STREAM(p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
566    }
567
568    if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
569      UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
570      UINT8_TO_STREAM(p, p_cfg->lb_h_info_resp_len);
571      ARRAY_TO_STREAM(p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
572    }
573
574    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
575  }
576
577  /*
578  ** Discovery Configuration Parameters for Listen NFC-DEP
579  */
580  if ((disc_mask &
581       (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP)) &&
582      (p_cfg->ln_enable)) {
583    p = params;
584
585    UINT8_TO_STREAM(p, NFC_PMID_WT);
586    UINT8_TO_STREAM(p, NCI_PARAM_LEN_WT);
587    UINT8_TO_STREAM(p, p_cfg->ln_wt);
588
589    UINT8_TO_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
590    UINT8_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes_len);
591    ARRAY_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes,
592                    p_cfg->ln_atr_res_gen_bytes_len);
593
594    UINT8_TO_STREAM(p, NFC_PMID_ATR_RSP_CONFIG);
595    UINT8_TO_STREAM(p, 1);
596    UINT8_TO_STREAM(p, p_cfg->ln_atr_res_config);
597
598    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
599  }
600
601  *p_disc_mask = disc_mask;
602
603  NFA_TRACE_DEBUG1("nfa_dm_set_rf_listen_mode_raw_config () disc_mask = 0x%x",
604                   disc_mask);
605}
606
607/*******************************************************************************
608**
609** Function         nfa_dm_disc_get_disc_mask
610**
611** Description      Convert RF technology, mode and protocol to bit mask
612**
613** Returns          tNFA_DM_DISC_TECH_PROTO_MASK
614**
615*******************************************************************************/
616static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
617    tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol) {
618  /* Set initial disc_mask to legacy poll or listen */
619  tNFA_DM_DISC_TECH_PROTO_MASK disc_mask =
620      ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY
621                            : NFA_DM_DISC_MASK_P_LEGACY);
622
623  if (NFC_DISCOVERY_TYPE_POLL_A == tech_n_mode) {
624    switch (protocol) {
625      case NFC_PROTOCOL_T1T:
626        disc_mask = NFA_DM_DISC_MASK_PA_T1T;
627        break;
628      case NFC_PROTOCOL_T2T:
629        disc_mask = NFA_DM_DISC_MASK_PA_T2T;
630        break;
631      case NFC_PROTOCOL_ISO_DEP:
632        disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
633        break;
634      case NFC_PROTOCOL_NFC_DEP:
635        disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
636        break;
637    }
638  } else if (NFC_DISCOVERY_TYPE_POLL_B == tech_n_mode) {
639    if (protocol == NFC_PROTOCOL_ISO_DEP)
640      disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
641  } else if (NFC_DISCOVERY_TYPE_POLL_F == tech_n_mode) {
642    if (protocol == NFC_PROTOCOL_T3T)
643      disc_mask = NFA_DM_DISC_MASK_PF_T3T;
644    else if (protocol == NFC_PROTOCOL_NFC_DEP)
645      disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
646  } else if (NFC_DISCOVERY_TYPE_POLL_V == tech_n_mode) {
647    disc_mask = NFA_DM_DISC_MASK_P_T5T;
648  } else if (NFC_DISCOVERY_TYPE_POLL_B_PRIME == tech_n_mode) {
649    disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
650  } else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == tech_n_mode) {
651    disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
652  } else if (NFC_DISCOVERY_TYPE_LISTEN_A == tech_n_mode) {
653    switch (protocol) {
654      case NFC_PROTOCOL_T1T:
655        disc_mask = NFA_DM_DISC_MASK_LA_T1T;
656        break;
657      case NFC_PROTOCOL_T2T:
658        disc_mask = NFA_DM_DISC_MASK_LA_T2T;
659        break;
660      case NFC_PROTOCOL_ISO_DEP:
661        disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
662        break;
663      case NFC_PROTOCOL_NFC_DEP:
664        disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
665        break;
666    }
667  } else if (NFC_DISCOVERY_TYPE_LISTEN_B == tech_n_mode) {
668    if (protocol == NFC_PROTOCOL_ISO_DEP)
669      disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
670  } else if (NFC_DISCOVERY_TYPE_LISTEN_F == tech_n_mode) {
671    if (protocol == NFC_PROTOCOL_T3T)
672      disc_mask = NFA_DM_DISC_MASK_LF_T3T;
673    else if (protocol == NFC_PROTOCOL_NFC_DEP)
674      disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
675  } else if (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == tech_n_mode) {
676    disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
677  } else if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == tech_n_mode) {
678    disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
679  }
680  if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
681    if (NFC_DISCOVERY_TYPE_POLL_ACTIVE == tech_n_mode) {
682      disc_mask = NFA_DM_DISC_MASK_PACM_NFC_DEP;
683    } else if (NFC_DISCOVERY_TYPE_LISTEN_ACTIVE == tech_n_mode) {
684      disc_mask = NFA_DM_DISC_MASK_LACM_NFC_DEP;
685    }
686  } else {
687    if (NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == tech_n_mode) {
688      disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
689    } else if (NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == tech_n_mode) {
690      disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
691    } else if (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == tech_n_mode) {
692      disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
693    } else if (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == tech_n_mode) {
694      disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
695    }
696  }
697
698  NFA_TRACE_DEBUG3(
699      "nfa_dm_disc_get_disc_mask (): tech_n_mode:0x%X, protocol:0x%X, "
700      "disc_mask:0x%X",
701      tech_n_mode, protocol, disc_mask);
702  return (disc_mask);
703}
704
705/*******************************************************************************
706**
707** Function         nfa_dm_disc_discovery_cback
708**
709** Description      Discovery callback event from NFC
710**
711** Returns          void
712**
713*******************************************************************************/
714static void nfa_dm_disc_discovery_cback(tNFC_DISCOVER_EVT event,
715                                        tNFC_DISCOVER* p_data) {
716  tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
717
718  NFA_TRACE_DEBUG1("nfa_dm_disc_discovery_cback (): event:0x%X", event);
719
720  switch (event) {
721    case NFC_START_DEVT:
722      dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
723      break;
724    case NFC_RESULT_DEVT:
725      dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
726      break;
727    case NFC_SELECT_DEVT:
728      dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
729      break;
730    case NFC_ACTIVATE_DEVT:
731      dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
732      break;
733    case NFC_DEACTIVATE_DEVT:
734      if (p_data->deactivate.is_ntf) {
735        dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
736        if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
737            (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
738          NFC_SetReassemblyFlag(true);
739          nfa_dm_cb.flags &= ~NFA_DM_FLAGS_RAW_FRAME;
740        }
741      } else
742        dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
743      break;
744    default:
745      NFA_TRACE_ERROR0("Unexpected event");
746      return;
747  }
748
749  nfa_dm_disc_sm_execute(dm_disc_event, (tNFA_DM_RF_DISC_DATA*)p_data);
750}
751
752/*******************************************************************************
753**
754** Function         nfa_dm_disc_notify_started
755**
756** Description      Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
757**                  NFA_RF_DISCOVERY_STARTED_EVT, if needed
758**
759** Returns          void
760**
761*******************************************************************************/
762static void nfa_dm_disc_notify_started(tNFA_STATUS status) {
763  tNFA_CONN_EVT_DATA evt_data;
764
765  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
766    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
767
768    evt_data.status = status;
769
770    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
771      nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
772                                     &evt_data);
773    else
774      nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
775  }
776}
777
778/*******************************************************************************
779**
780** Function         nfa_dm_disc_conn_event_notify
781**
782** Description      Notify application of CONN_CBACK event, using appropriate
783**                  callback
784**
785** Returns          nothing
786**
787*******************************************************************************/
788void nfa_dm_disc_conn_event_notify(uint8_t event, tNFA_STATUS status) {
789  tNFA_CONN_EVT_DATA evt_data;
790
791  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
792    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
793    evt_data.status = status;
794
795    if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
796      /* Use exclusive RF mode callback */
797      if (nfa_dm_cb.p_excl_conn_cback)
798        (*nfa_dm_cb.p_excl_conn_cback)(event, &evt_data);
799    } else {
800      (*nfa_dm_cb.p_conn_cback)(event, &evt_data);
801    }
802  }
803}
804
805/*******************************************************************************
806**
807** Function         nfa_dm_disc_force_to_idle
808**
809** Description      Force NFCC to idle state while waiting for deactivation NTF
810**
811** Returns          tNFC_STATUS
812**
813*******************************************************************************/
814static tNFC_STATUS nfa_dm_disc_force_to_idle(void) {
815  tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
816
817  NFA_TRACE_DEBUG1("nfa_dm_disc_force_to_idle() disc_flags = 0x%x",
818                   nfa_dm_cb.disc_cb.disc_flags);
819
820  /* do not execute more than one */
821  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
822    nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
823    nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
824    nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
825    status = NFC_Deactivate(NFC_DEACTIVATE_TYPE_IDLE);
826  }
827
828  return (status);
829}
830
831/*******************************************************************************
832**
833** Function         nfa_dm_disc_deact_ntf_timeout_cback
834**
835** Description      Timeout while waiting for deactivation NTF
836**
837** Returns          void
838**
839*******************************************************************************/
840static void nfa_dm_disc_deact_ntf_timeout_cback(TIMER_LIST_ENT* p_tle) {
841  NFA_TRACE_ERROR0("nfa_dm_disc_deact_ntf_timeout_cback()");
842
843  nfa_dm_disc_force_to_idle();
844}
845
846/*******************************************************************************
847**
848** Function         nfa_dm_send_deactivate_cmd
849**
850** Description      Send deactivate command to NFCC, if needed.
851**
852** Returns          NFC_STATUS_OK             - deactivate cmd is sent
853**                  NCI_STATUS_FAILED         - no buffers
854**                  NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
855**                                              to send deactivate cmd
856**
857*******************************************************************************/
858static tNFC_STATUS nfa_dm_send_deactivate_cmd(tNFC_DEACT_TYPE deactivate_type) {
859  tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
860  tNFA_DM_DISC_FLAGS w4_flags =
861      nfa_dm_cb.disc_cb.disc_flags &
862      (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
863
864  if (!w4_flags) {
865    /* if deactivate CMD was not sent to NFCC */
866    nfa_dm_cb.disc_cb.disc_flags |=
867        (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
868
869    status = NFC_Deactivate(deactivate_type);
870
871    if (!nfa_dm_cb.disc_cb.tle.in_use) {
872      nfa_dm_cb.disc_cb.tle.p_cback =
873          (TIMER_CBACK*)nfa_dm_disc_deact_ntf_timeout_cback;
874      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0,
875                          NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF);
876    }
877  } else {
878    if (deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP) {
879      status = NFC_STATUS_SEMANTIC_ERROR;
880    } else if (nfa_dm_cb.disc_cb.tle.in_use) {
881      status = NFC_STATUS_OK;
882    } else {
883      status = nfa_dm_disc_force_to_idle();
884    }
885  }
886
887  return status;
888}
889
890/*******************************************************************************
891**
892** Function         nfa_dm_start_rf_discover
893**
894** Description      Start RF discovery
895**
896** Returns          void
897**
898*******************************************************************************/
899void nfa_dm_start_rf_discover(void) {
900  tNFC_DISCOVER_PARAMS disc_params[NFA_DM_MAX_DISC_PARAMS];
901  tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0, poll_mask, listen_mask;
902  uint8_t config_params[10], *p;
903  uint8_t num_params, xx;
904
905  NFA_TRACE_DEBUG0("nfa_dm_start_rf_discover ()");
906  /* Make sure that RF discovery was enabled, or some app has exclusive control
907   */
908  if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)) &&
909      (nfa_dm_cb.disc_cb.excl_disc_entry.in_use == false)) {
910    return;
911  }
912
913  /* get listen mode routing table for technology */
914  nfa_ee_get_tech_route(NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
915
916  if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
917    nfa_dm_set_rf_listen_mode_raw_config(&dm_disc_mask);
918    dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask &
919                     NFA_DM_DISC_MASK_POLL);
920    nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
921  } else {
922    /* Collect RF discovery request from sub-modules */
923    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
924      if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
925        poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
926                     NFA_DM_DISC_MASK_POLL);
927
928        /* clear poll mode technolgies and protocols which are already used by
929         * others */
930        poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
931
932        listen_mask = 0;
933
934        /*
935        ** add listen mode technolgies and protocols if host ID is
936        ** matched to listen mode routing table
937        */
938
939        /* NFC-A */
940        if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
941            nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A]) {
942          listen_mask |=
943              nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
944              (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
945               NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
946          if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
947            listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
948                           NFA_DM_DISC_MASK_LACM_NFC_DEP;
949          } else {
950            listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
951                           NFA_DM_DISC_MASK_LAA_NFC_DEP;
952          }
953        } else {
954          /* host can listen ISO-DEP based on AID routing */
955          listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
956                          NFA_DM_DISC_MASK_LA_ISO_DEP);
957          if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
958            listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
959                            NFA_DM_DISC_MASK_LACM_NFC_DEP);
960          } else {
961            /* host can listen NFC-DEP based on protocol routing */
962            listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
963                            NFA_DM_DISC_MASK_LA_NFC_DEP);
964            listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
965                            NFA_DM_DISC_MASK_LAA_NFC_DEP);
966          }
967        }
968
969        /* NFC-B */
970        /* multiple hosts can listen ISO-DEP based on AID routing */
971        listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
972                       NFA_DM_DISC_MASK_LB_ISO_DEP;
973
974        /* NFC-F */
975        /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
976         * regardless of NFC-F tech routing */
977        listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
978                       (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP);
979        if (NFC_GetNCIVersion() != NCI_VERSION_2_0) {
980          listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
981                         NFA_DM_DISC_MASK_LFA_NFC_DEP;
982        }
983        /* NFC-B Prime */
984        if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
985            nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP]) {
986          listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
987                         NFA_DM_DISC_MASK_L_B_PRIME;
988        }
989
990        /*
991        ** clear listen mode technolgies and protocols which are already
992        ** used by others
993        */
994
995        /* Check if other modules are listening T1T or T2T */
996        if (dm_disc_mask &
997            (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T)) {
998          listen_mask &=
999              ~(NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
1000                NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
1001        }
1002
1003        /* T1T/T2T has priority on NFC-A */
1004        if ((dm_disc_mask &
1005             (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) &&
1006            (listen_mask &
1007             (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T))) {
1008          dm_disc_mask &=
1009              ~(NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
1010        }
1011
1012        /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based
1013         * on AID routing */
1014
1015        /* Check if other modules are listening NFC-DEP */
1016        if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
1017          if (dm_disc_mask &
1018              (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LACM_NFC_DEP)) {
1019            listen_mask &=
1020                ~(NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LACM_NFC_DEP);
1021          }
1022        } else {
1023          if (dm_disc_mask &
1024              (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP)) {
1025            listen_mask &=
1026                ~(NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP);
1027          }
1028        }
1029
1030        nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask =
1031            poll_mask | listen_mask;
1032
1033        NFA_TRACE_DEBUG2(
1034            "nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x", xx,
1035            nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
1036
1037        dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
1038      }
1039    }
1040
1041    /* Let P2P set GEN bytes for LLCP to NFCC */
1042    if (dm_disc_mask & NFA_DM_DISC_MASK_NFC_DEP) {
1043      nfa_p2p_set_config(dm_disc_mask);
1044    }
1045    if (dm_disc_mask &
1046        (NFA_DM_DISC_MASK_PF_NFC_DEP | NFA_DM_DISC_MASK_PF_T3T)) {
1047      /* According to the NFC Forum Activity spec, controllers must:
1048       * 1) Poll with RC=0 and SC=FFFF to find NFC-DEP targets
1049       * 2) Poll with RC=1 and SC=FFFF to find T3T targets
1050       * Many controllers don't do this yet, and seem to be activating
1051       * NFC-DEP by default.
1052       *
1053       * We can at least fix the scenario where we're not interested
1054       * in NFC-DEP, by setting RC=1 in that case. Otherwise, keep
1055       * the default of RC=0. */
1056      p = config_params;
1057      UINT8_TO_STREAM(p, NFC_PMID_PF_RC);
1058      UINT8_TO_STREAM(p, NCI_PARAM_LEN_PF_RC);
1059      if ((dm_disc_mask & NFA_DM_DISC_MASK_PF_NFC_DEP) &&
1060          !nfa_dm_is_p2p_paused()) {
1061        UINT8_TO_STREAM(p, 0x00);  // RC=0
1062      } else {
1063        UINT8_TO_STREAM(p, 0x01);  // RC=1
1064      }
1065      nfa_dm_check_set_config(p - config_params, config_params, false);
1066    }
1067  }
1068
1069  NFA_TRACE_DEBUG1("dm_disc_mask = 0x%x", dm_disc_mask);
1070
1071  /* Get Discovery Technology parameters */
1072  num_params = nfa_dm_get_rf_discover_config(dm_disc_mask, disc_params,
1073                                             NFA_DM_MAX_DISC_PARAMS);
1074
1075  if (num_params) {
1076    /*
1077    ** NFCC will abort programming personality slots if not available.
1078    ** NFCC programs the personality slots in the following order of RF
1079    ** technologies: NFC-A, NFC-B, NFC-BP, NFC-I93
1080    */
1081
1082    /* if this is not for exclusive control */
1083    if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1084      /* update listening protocols in each NFC technology */
1085      nfa_dm_set_rf_listen_mode_config(dm_disc_mask);
1086    }
1087
1088    /* Set polling duty cycle */
1089    nfa_dm_set_total_duration();
1090    nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
1091
1092    NFC_DiscoveryStart(num_params, disc_params, nfa_dm_disc_discovery_cback);
1093    /* set flag about waiting for response in IDLE state */
1094    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1095
1096    /* register callback to get interface error NTF */
1097    NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
1098  } else {
1099    /* RF discovery is started but there is no valid technology or protocol to
1100     * discover */
1101    nfa_dm_disc_notify_started(NFA_STATUS_OK);
1102  }
1103
1104  /* if Kovio presence check timer is running, timeout callback will reset the
1105   * activation information */
1106  if ((nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO) ||
1107      (!nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1108    /* reset protocol and hanlde of activated sub-module */
1109    nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1110    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1111  }
1112}
1113
1114/*******************************************************************************
1115**
1116** Function         nfa_dm_notify_discovery
1117**
1118** Description      Send RF discovery notification to upper layer
1119**
1120** Returns          void
1121**
1122*******************************************************************************/
1123static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data) {
1124  tNFA_CONN_EVT_DATA conn_evt;
1125
1126  /* let application select a device */
1127  conn_evt.disc_result.status = NFA_STATUS_OK;
1128  memcpy(&(conn_evt.disc_result.discovery_ntf), &(p_data->nfc_discover.result),
1129         sizeof(tNFC_RESULT_DEVT));
1130
1131  nfa_dm_conn_cback_event_notify(NFA_DISC_RESULT_EVT, &conn_evt);
1132}
1133
1134/*******************************************************************************
1135**
1136** Function         nfa_dm_disc_handle_kovio_activation
1137**
1138** Description      Handle Kovio activation; whether it's new or repeated
1139**                  activation
1140**
1141** Returns          TRUE if repeated activation. No need to notify activated
1142**                  event to upper layer
1143**
1144*******************************************************************************/
1145bool nfa_dm_disc_handle_kovio_activation(tNFC_DISCOVER* p_data,
1146                                         tNFA_DISCOVER_CBACK* p_disc_cback) {
1147  tNFC_DISCOVER disc_data;
1148
1149  if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
1150    /* if this is new Kovio bar code tag */
1151    if ((nfa_dm_cb.activated_nfcid_len !=
1152         p_data->activate.rf_tech_param.param.pk.uid_len) ||
1153        (memcmp(p_data->activate.rf_tech_param.param.pk.uid,
1154                nfa_dm_cb.activated_nfcid, nfa_dm_cb.activated_nfcid_len))) {
1155      NFA_TRACE_DEBUG0("new Kovio tag is detected");
1156
1157      /* notify presence check failure for previous tag, if presence check is
1158       * pending */
1159      nfa_dm_disc_report_kovio_presence_check(NFA_STATUS_FAILED);
1160
1161      /* notify deactivation of previous activation before notifying new
1162       * activation */
1163      if (p_disc_cback) {
1164        disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1165        (*(p_disc_cback))(NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1166      }
1167
1168      /* restart timer */
1169      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1170                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1171    } else {
1172      /* notify presence check ok, if presence check is pending */
1173      nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_OK);
1174
1175      /* restart timer and do not notify upper layer */
1176      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1177                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1178      return true;
1179    }
1180  } else {
1181    /* this is the first activation, so start timer and notify upper layer */
1182    nfa_dm_cb.disc_cb.kovio_tle.p_cback =
1183        (TIMER_CBACK*)nfa_dm_disc_kovio_timeout_cback;
1184    nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1185                        NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1186  }
1187
1188  return false;
1189}
1190
1191/*******************************************************************************
1192**
1193** Function         nfa_dm_disc_notify_activation
1194**
1195** Description      Send RF activation notification to sub-module
1196**
1197** Returns          NFA_STATUS_OK if success
1198**
1199*******************************************************************************/
1200static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data) {
1201  uint8_t xx, host_id_in_LRT;
1202  uint8_t iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
1203
1204  tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
1205  tNFC_PROTOCOL protocol = p_data->activate.protocol;
1206
1207  tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
1208
1209  NFA_TRACE_DEBUG2(
1210      "nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
1211      tech_n_mode, protocol);
1212
1213  if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1214    nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1215    nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1216    nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1217    nfa_dm_cb.disc_cb.activated_protocol = protocol;
1218    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1219
1220    if (protocol == NFC_PROTOCOL_KOVIO) {
1221      /* check whether it's new or repeated activation */
1222      if (nfa_dm_disc_handle_kovio_activation(
1223              p_data, nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) {
1224        /* do not notify activation of Kovio to upper layer */
1225        return (NFA_STATUS_OK);
1226      }
1227    }
1228
1229    if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1230      (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1231          NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1232
1233    return (NFA_STATUS_OK);
1234  }
1235
1236  /* if this is NFCEE direct RF interface, notify activation to whoever
1237   * listening UICC */
1238  if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF) {
1239    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1240      if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1241          (nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH)) {
1242        nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1243        nfa_dm_cb.disc_cb.activated_rf_interface =
1244            p_data->activate.intf_param.type;
1245        nfa_dm_cb.disc_cb.activated_protocol = NFC_PROTOCOL_UNKNOWN;
1246        nfa_dm_cb.disc_cb.activated_handle = xx;
1247
1248        NFA_TRACE_DEBUG2("activated_rf_interface:0x%x, activated_handle: 0x%x",
1249                         nfa_dm_cb.disc_cb.activated_rf_interface,
1250                         nfa_dm_cb.disc_cb.activated_handle);
1251
1252        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1253          (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1254              NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1255
1256        return (NFA_STATUS_OK);
1257      }
1258    }
1259    return (NFA_STATUS_FAILED);
1260  }
1261
1262  /* get bit mask of technolgies/mode and protocol */
1263  activated_disc_mask = nfa_dm_disc_get_disc_mask(tech_n_mode, protocol);
1264
1265  /* get host ID of technology from listen mode routing table */
1266  if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
1267    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
1268  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
1269    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
1270  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
1271    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
1272  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
1273    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
1274  } else /* DH only */
1275  {
1276    host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1277  }
1278
1279  if (protocol == NFC_PROTOCOL_NFC_DEP) {
1280    /* Force NFC-DEP to the host */
1281    host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1282  }
1283
1284  for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1285    /* if any matching NFC technology and protocol */
1286    if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
1287      if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT) {
1288        if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1289            activated_disc_mask)
1290          break;
1291      } else {
1292        /* check ISO-DEP listening even if host in LRT is not matched */
1293        if (protocol == NFC_PROTOCOL_ISO_DEP) {
1294          if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) &&
1295              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1296               NFA_DM_DISC_MASK_LA_ISO_DEP)) {
1297            iso_dep_t3t__listen = xx;
1298          } else if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) &&
1299                     (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1300                      NFA_DM_DISC_MASK_LB_ISO_DEP)) {
1301            iso_dep_t3t__listen = xx;
1302          }
1303        }
1304        /* check T3T listening even if host in LRT is not matched */
1305        else if (protocol == NFC_PROTOCOL_T3T) {
1306          if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) &&
1307              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1308               NFA_DM_DISC_MASK_LF_T3T)) {
1309            iso_dep_t3t__listen = xx;
1310          }
1311        }
1312      }
1313    }
1314  }
1315
1316  if (xx >= NFA_DM_DISC_NUM_ENTRIES) {
1317    /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
1318    xx = iso_dep_t3t__listen;
1319  }
1320
1321  if (xx < NFA_DM_DISC_NUM_ENTRIES) {
1322    nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1323    nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1324    nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1325    nfa_dm_cb.disc_cb.activated_protocol = protocol;
1326    nfa_dm_cb.disc_cb.activated_handle = xx;
1327
1328    NFA_TRACE_DEBUG2("activated_protocol:0x%x, activated_handle: 0x%x",
1329                     nfa_dm_cb.disc_cb.activated_protocol,
1330                     nfa_dm_cb.disc_cb.activated_handle);
1331
1332    if (protocol == NFC_PROTOCOL_KOVIO) {
1333      /* check whether it's new or repeated activation */
1334      if (nfa_dm_disc_handle_kovio_activation(
1335              p_data, nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
1336        /* do not notify activation of Kovio to upper layer */
1337        return (NFA_STATUS_OK);
1338      }
1339    }
1340
1341    if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1342      (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1343          NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1344
1345    return (NFA_STATUS_OK);
1346  } else {
1347    nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1348    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1349    return (NFA_STATUS_FAILED);
1350  }
1351}
1352
1353/*******************************************************************************
1354**
1355** Function         nfa_dm_disc_notify_deactivation
1356**
1357** Description      Send deactivation notification to sub-module
1358**
1359** Returns          None
1360**
1361*******************************************************************************/
1362static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
1363                                            tNFC_DISCOVER* p_data) {
1364  tNFA_HANDLE xx;
1365  tNFA_CONN_EVT_DATA evt_data;
1366  tNFC_DISCOVER disc_data;
1367
1368  NFA_TRACE_DEBUG1("nfa_dm_disc_notify_deactivation (): activated_handle=%d",
1369                   nfa_dm_cb.disc_cb.activated_handle);
1370
1371  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1372    NFA_TRACE_DEBUG0("nfa_dm_disc_notify_deactivation (): for sleep wakeup");
1373    return;
1374  }
1375
1376  if (sm_event == NFA_DM_RF_DEACTIVATE_RSP) {
1377    /*
1378    ** Activation has been aborted by upper layer in
1379    ** NFA_DM_RFST_W4_ALL_DISCOVERIES or NFA_DM_RFST_W4_HOST_SELECT
1380    ** Deactivation by upper layer or RF link loss in
1381    ** NFA_DM_RFST_LISTEN_SLEEP
1382    ** No sub-module is activated at this state.
1383    */
1384
1385    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_SLEEP) {
1386      if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1387        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1388          disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1389          (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1390              NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1391        }
1392      } else {
1393        /* let each sub-module handle deactivation */
1394        for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1395          if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1396              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
1397               NFA_DM_DISC_MASK_LISTEN)) {
1398            disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1399            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1400                NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1401          }
1402        }
1403      }
1404    } else if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)) ||
1405               (nfa_dm_cb.disc_cb.deact_notify_pending)) {
1406      xx = nfa_dm_cb.disc_cb.activated_handle;
1407
1408      /* notify event to activated module if failed while reactivation */
1409      if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1410        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1411          disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1412          (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1413              NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1414        }
1415      } else if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
1416                 (nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1417                 (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
1418        (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1419            NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1420      } else {
1421        /* notify deactivation to application if there is no activated module */
1422        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1423        nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1424      }
1425    }
1426  } else {
1427    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) {
1428      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
1429        /* restart timer and do not notify upper layer */
1430        nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1431                            NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1432        return;
1433      }
1434      /* Otherwise, upper layer initiated deactivation. */
1435    }
1436
1437    /* notify event to activated module */
1438    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1439      if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
1440        disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1441        (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1442            NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1443      }
1444    } else {
1445      xx = nfa_dm_cb.disc_cb.activated_handle;
1446
1447      if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
1448          (nfa_dm_cb.disc_cb.entry[xx].in_use)) {
1449        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1450          (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1451              NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1452      }
1453    }
1454  }
1455
1456  /* clear activated information */
1457  nfa_dm_cb.disc_cb.activated_tech_mode = 0;
1458  nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
1459  nfa_dm_cb.disc_cb.activated_rf_interface = 0;
1460  nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1461  nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1462  nfa_dm_cb.disc_cb.deact_notify_pending = false;
1463}
1464
1465/*******************************************************************************
1466**
1467** Function         nfa_dm_disc_sleep_wakeup
1468**
1469** Description      Put tag to sleep, then wake it up. Can be used Perform
1470**                  legacy presence check or to wake up tag that went to HALT
1471**                  state
1472**
1473** Returns          TRUE if operation started
1474**
1475*******************************************************************************/
1476tNFC_STATUS nfa_dm_disc_sleep_wakeup(void) {
1477  tNFC_STATUS status = NFC_STATUS_FAILED;
1478
1479  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1480    /* Deactivate to sleep mode */
1481    status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
1482    if (status == NFC_STATUS_OK) {
1483      /* deactivate to sleep is sent on behalf of sleep wakeup.
1484       * set the sleep wakeup information in control block */
1485      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1486      nfa_dm_cb.disc_cb.deact_pending = false;
1487    }
1488  }
1489
1490  return (status);
1491}
1492
1493/*******************************************************************************
1494**
1495** Function         nfa_dm_is_raw_frame_session
1496**
1497** Description      If NFA_SendRawFrame is called since RF activation,
1498**                  this function returns TRUE.
1499**
1500** Returns          TRUE if NFA_SendRawFrame is called
1501**
1502*******************************************************************************/
1503bool nfa_dm_is_raw_frame_session(void) {
1504  return ((nfa_dm_cb.flags & NFA_DM_FLAGS_RAW_FRAME) ? true : false);
1505}
1506
1507/*******************************************************************************
1508**
1509** Function         nfa_dm_is_p2p_paused
1510**
1511** Description      If NFA_PauseP2p is called sand still effective,
1512**                  this function returns TRUE.
1513**
1514** Returns          TRUE if NFA_SendRawFrame is called
1515**
1516*******************************************************************************/
1517bool nfa_dm_is_p2p_paused(void) {
1518  return ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) ? true : false);
1519}
1520
1521/*******************************************************************************
1522**
1523** Function         nfa_dm_disc_end_sleep_wakeup
1524**
1525** Description      Sleep Wakeup is complete
1526**
1527** Returns          None
1528**
1529*******************************************************************************/
1530static void nfa_dm_disc_end_sleep_wakeup(tNFC_STATUS status) {
1531  if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
1532      (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1533    /* ignore it while doing Kovio presence check */
1534    return;
1535  }
1536
1537  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1538    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1539
1540    /* notify RW module that sleep wakeup is finished */
1541    nfa_rw_handle_sleep_wakeup_rsp(status);
1542
1543    if (nfa_dm_cb.disc_cb.deact_pending) {
1544      nfa_dm_cb.disc_cb.deact_pending = false;
1545      /* Perform pending deactivate command and on response notfiy deactivation
1546       */
1547      nfa_dm_cb.disc_cb.deact_notify_pending = true;
1548      nfa_dm_disc_sm_execute(
1549          NFA_DM_RF_DEACTIVATE_CMD,
1550          (tNFA_DM_RF_DISC_DATA*)&nfa_dm_cb.disc_cb.pending_deact_type);
1551    }
1552  }
1553}
1554
1555/*******************************************************************************
1556**
1557** Function         nfa_dm_disc_kovio_timeout_cback
1558**
1559** Description      Timeout for Kovio bar code tag presence check
1560**
1561** Returns          void
1562**
1563*******************************************************************************/
1564static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle) {
1565  tNFC_DEACTIVATE_DEVT deact;
1566
1567  NFA_TRACE_DEBUG0("nfa_dm_disc_kovio_timeout_cback()");
1568
1569  /* notify presence check failure, if presence check is pending */
1570  nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_FAILED);
1571
1572  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1573    /* restart timer in case that upper layer's presence check interval is too
1574     * long */
1575    nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1576                        NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1577  } else {
1578    /* notify upper layer deactivated event */
1579    deact.status = NFC_STATUS_OK;
1580    deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
1581    deact.is_ntf = true;
1582    nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
1583                                    (tNFC_DISCOVER*)&deact);
1584  }
1585}
1586
1587/*******************************************************************************
1588**
1589** Function         nfa_dm_disc_start_kovio_presence_check
1590**
1591** Description      Deactivate to discovery mode and wait for activation
1592**
1593** Returns          TRUE if operation started
1594**
1595*******************************************************************************/
1596tNFC_STATUS nfa_dm_disc_start_kovio_presence_check(void) {
1597  tNFC_STATUS status = NFC_STATUS_FAILED;
1598
1599  NFA_TRACE_DEBUG0("nfa_dm_disc_start_kovio_presence_check ()");
1600
1601  if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
1602      (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
1603    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
1604      /* restart timer */
1605      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
1606                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1607
1608      /* Deactivate to discovery mode */
1609      status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_DISCOVERY);
1610
1611      if (status == NFC_STATUS_OK) {
1612        /* deactivate to sleep is sent on behalf of sleep wakeup.
1613         * set the sleep wakeup information in control block */
1614        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1615        nfa_dm_cb.disc_cb.deact_pending = false;
1616      }
1617    } else {
1618      /* wait for next activation */
1619      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1620      nfa_dm_cb.disc_cb.deact_pending = false;
1621      status = NFC_STATUS_OK;
1622    }
1623  }
1624
1625  return (status);
1626}
1627
1628/*******************************************************************************
1629**
1630** Function         nfa_dm_disc_report_kovio_presence_check
1631**
1632** Description      Report Kovio presence check status
1633**
1634** Returns          None
1635**
1636*******************************************************************************/
1637static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status) {
1638  NFA_TRACE_DEBUG0("nfa_dm_disc_report_kovio_presence_check ()");
1639
1640  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
1641    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1642
1643    /* notify RW module that sleep wakeup is finished */
1644    nfa_rw_handle_presence_check_rsp(status);
1645
1646    if (nfa_dm_cb.disc_cb.deact_pending) {
1647      nfa_dm_cb.disc_cb.deact_pending = false;
1648      nfa_dm_disc_sm_execute(
1649          NFA_DM_RF_DEACTIVATE_CMD,
1650          (tNFA_DM_RF_DISC_DATA*)&nfa_dm_cb.disc_cb.pending_deact_type);
1651    }
1652  }
1653}
1654
1655/*******************************************************************************
1656**
1657** Function         nfa_dm_disc_data_cback
1658**
1659** Description      Monitoring interface error through data callback
1660**
1661** Returns          void
1662**
1663*******************************************************************************/
1664static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
1665                                   tNFC_CONN* p_data) {
1666  NFA_TRACE_DEBUG0("nfa_dm_disc_data_cback ()");
1667
1668  /* if selection failed */
1669  if (event == NFC_ERROR_CEVT) {
1670    nfa_dm_disc_sm_execute(NFA_DM_CORE_INTF_ERROR_NTF, NULL);
1671  } else if (event == NFC_DATA_CEVT) {
1672    GKI_freebuf(p_data->data.p_data);
1673  }
1674}
1675
1676/*******************************************************************************
1677**
1678** Function         nfa_dm_disc_new_state
1679**
1680** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1681**
1682** Returns          void
1683**
1684*******************************************************************************/
1685void nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state) {
1686  tNFA_CONN_EVT_DATA evt_data;
1687  tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
1688
1689#if (BT_TRACE_VERBOSE == TRUE)
1690  NFA_TRACE_DEBUG5(
1691      "nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) "
1692      "disc_flags: 0x%x",
1693      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
1694      nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_state_2_str(new_state),
1695      new_state, nfa_dm_cb.disc_cb.disc_flags);
1696#else
1697  NFA_TRACE_DEBUG3(
1698      "nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
1699      nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
1700#endif
1701
1702  nfa_dm_cb.disc_cb.disc_state = new_state;
1703
1704  /* not error recovering */
1705  if ((new_state == NFA_DM_RFST_IDLE) &&
1706      (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
1707    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
1708      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
1709
1710      /* if exclusive RF control is stopping */
1711      if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
1712        if (old_state > NFA_DM_RFST_DISCOVERY) {
1713          /* notify deactivation to application */
1714          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1715          nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1716        }
1717
1718        nfa_dm_rel_excl_rf_control_and_notify();
1719      } else {
1720        evt_data.status = NFA_STATUS_OK;
1721        nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
1722      }
1723    }
1724    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) {
1725      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
1726      nfa_sys_check_disabled();
1727    }
1728  }
1729}
1730
1731/*******************************************************************************
1732**
1733** Function         nfa_dm_disc_sm_idle
1734**
1735** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1736**
1737** Returns          void
1738**
1739*******************************************************************************/
1740static void nfa_dm_disc_sm_idle(tNFA_DM_RF_DISC_SM_EVENT event,
1741                                tNFA_DM_RF_DISC_DATA* p_data) {
1742  uint8_t xx;
1743
1744  switch (event) {
1745    case NFA_DM_RF_DISCOVER_CMD:
1746      nfa_dm_start_rf_discover();
1747      break;
1748
1749    case NFA_DM_RF_DISCOVER_RSP:
1750      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1751
1752      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
1753        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
1754
1755        /* if RF discovery was stopped while waiting for response */
1756        if (nfa_dm_cb.disc_cb.disc_flags &
1757            (NFA_DM_DISC_FLAGS_STOPPING | NFA_DM_DISC_FLAGS_DISABLING)) {
1758          /* stop discovery */
1759          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1760          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1761          break;
1762        }
1763
1764        if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
1765          if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &
1766              NFA_DM_DISC_FLAGS_NOTIFY) {
1767            nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &=
1768                ~NFA_DM_DISC_FLAGS_NOTIFY;
1769
1770            if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1771              (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
1772                  NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*)p_data);
1773          }
1774        } else {
1775          /* notify event to each module which is waiting for start */
1776          for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
1777            /* if registered module is waiting for starting discovery */
1778            if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
1779                (nfa_dm_cb.disc_cb.dm_disc_mask &
1780                 nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask) &&
1781                (nfa_dm_cb.disc_cb.entry[xx].disc_flags &
1782                 NFA_DM_DISC_FLAGS_NOTIFY)) {
1783              nfa_dm_cb.disc_cb.entry[xx].disc_flags &=
1784                  ~NFA_DM_DISC_FLAGS_NOTIFY;
1785
1786              if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1787                (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
1788                    NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*)p_data);
1789            }
1790          }
1791        }
1792        nfa_dm_disc_notify_started(p_data->nfc_discover.status);
1793      } else {
1794        /* in rare case that the discovery states of NFCC and DH mismatch and
1795         * NFCC rejects Discover Cmd
1796         * deactivate idle and then start disvocery when got deactivate rsp */
1797        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1798        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1799      }
1800      break;
1801
1802    case NFA_DM_RF_DEACTIVATE_RSP:
1803      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1804
1805      /* if NFCC goes to idle successfully */
1806      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
1807        /* if DH forced to go idle while waiting for deactivation NTF */
1808        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1809          nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
1810                                          &(p_data->nfc_discover));
1811
1812          /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
1813           * NFA_DM_DISC_FLAGS_DISABLING */
1814          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1815          /* check if need to restart discovery after resync discovery state
1816           * with NFCC */
1817          nfa_dm_start_rf_discover();
1818        }
1819        /* Otherwise, deactivating when getting unexpected activation */
1820      }
1821      /* Otherwise, wait for deactivation NTF */
1822      break;
1823
1824    case NFA_DM_RF_DEACTIVATE_NTF:
1825      /* if NFCC sent this after NFCC had rejected deactivate CMD to idle while
1826       * deactivating */
1827      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1828        if (p_data->nfc_discover.deactivate.type ==
1829            NFC_DEACTIVATE_TYPE_DISCOVERY) {
1830          /* stop discovery */
1831          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1832          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1833        } else {
1834          nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
1835                                          &(p_data->nfc_discover));
1836          /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
1837           * NFA_DM_DISC_FLAGS_DISABLING */
1838          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1839          /* check if need to restart discovery after resync discovery state
1840           * with NFCC */
1841          nfa_dm_start_rf_discover();
1842        }
1843      }
1844      /* Otherwise, deactivated when received unexpected activation in idle
1845       * state */
1846      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1847      break;
1848
1849    case NFA_DM_RF_INTF_ACTIVATED_NTF:
1850      /* unexpected activation, deactivate to idle */
1851      nfa_dm_cb.disc_cb.disc_flags |=
1852          (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
1853      NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1854      break;
1855
1856    case NFA_DM_LP_LISTEN_CMD:
1857      nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
1858      break;
1859
1860    default:
1861      NFA_TRACE_ERROR0("nfa_dm_disc_sm_idle (): Unexpected discovery event");
1862      break;
1863  }
1864}
1865
1866/*******************************************************************************
1867**
1868** Function         nfa_dm_disc_sm_discovery
1869**
1870** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
1871**
1872** Returns          void
1873**
1874*******************************************************************************/
1875static void nfa_dm_disc_sm_discovery(tNFA_DM_RF_DISC_SM_EVENT event,
1876                                     tNFA_DM_RF_DISC_DATA* p_data) {
1877  switch (event) {
1878    case NFA_DM_RF_DEACTIVATE_CMD:
1879      /* if deactivate CMD was not sent to NFCC */
1880      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1881        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1882        NFC_Deactivate(p_data->deactivate_type);
1883      }
1884      break;
1885    case NFA_DM_RF_DEACTIVATE_RSP:
1886      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1887
1888      /* if it's not race condition between deactivate CMD and activate NTF */
1889      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
1890        /* do not notify deactivated to idle in RF discovery state
1891        ** because it is internal or stopping RF discovery
1892        */
1893
1894        /* there was no activation while waiting for deactivation RSP */
1895        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1896        nfa_dm_start_rf_discover();
1897      }
1898      break;
1899    case NFA_DM_RF_DISCOVER_NTF:
1900      nfa_dm_disc_new_state(NFA_DM_RFST_W4_ALL_DISCOVERIES);
1901      nfa_dm_notify_discovery(p_data);
1902      break;
1903    case NFA_DM_RF_INTF_ACTIVATED_NTF:
1904      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
1905        NFA_TRACE_DEBUG0("RF Activated while waiting for deactivation RSP");
1906        /* it's race condition. DH has to wait for deactivation NTF */
1907        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
1908      } else {
1909        if (p_data->nfc_discover.activate.intf_param.type ==
1910            NFC_INTERFACE_EE_DIRECT_RF) {
1911          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
1912        } else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80) {
1913          /* Listen mode */
1914          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
1915        } else {
1916          /* Poll mode */
1917          nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
1918        }
1919
1920        if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
1921            NFA_STATUS_FAILED) {
1922          NFA_TRACE_DEBUG0(
1923              "Not matched, restart discovery after receiving deactivate ntf");
1924
1925          /* after receiving deactivate event, restart discovery */
1926          nfa_dm_cb.disc_cb.disc_flags |=
1927              (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
1928          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1929        }
1930      }
1931      break;
1932
1933    case NFA_DM_RF_DEACTIVATE_NTF:
1934      /* if there was race condition between deactivate CMD and activate NTF */
1935      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
1936        /* race condition is resolved */
1937        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1938
1939        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1940          /* do not notify deactivated to idle in RF discovery state
1941          ** because it is internal or stopping RF discovery
1942          */
1943
1944          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1945          nfa_dm_start_rf_discover();
1946        }
1947      }
1948      break;
1949    case NFA_DM_LP_LISTEN_CMD:
1950      break;
1951    case NFA_DM_CORE_INTF_ERROR_NTF:
1952      break;
1953    default:
1954      NFA_TRACE_ERROR0(
1955          "nfa_dm_disc_sm_discovery (): Unexpected discovery event");
1956      break;
1957  }
1958}
1959
1960/*******************************************************************************
1961**
1962** Function         nfa_dm_disc_sm_w4_all_discoveries
1963**
1964** Description      Processing discovery events in
1965**                  NFA_DM_RFST_W4_ALL_DISCOVERIES state
1966**
1967** Returns          void
1968**
1969*******************************************************************************/
1970static void nfa_dm_disc_sm_w4_all_discoveries(tNFA_DM_RF_DISC_SM_EVENT event,
1971                                              tNFA_DM_RF_DISC_DATA* p_data) {
1972  switch (event) {
1973    case NFA_DM_RF_DEACTIVATE_CMD:
1974      /* if deactivate CMD was not sent to NFCC */
1975      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1976        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1977        /* only IDLE mode is allowed */
1978        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
1979      }
1980      break;
1981    case NFA_DM_RF_DEACTIVATE_RSP:
1982      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1983      /* notify exiting from w4 all discoverie state */
1984      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
1985                                      &(p_data->nfc_discover));
1986
1987      nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
1988      nfa_dm_start_rf_discover();
1989      break;
1990    case NFA_DM_RF_DISCOVER_NTF:
1991      /* if deactivate CMD is already sent then ignore discover NTF */
1992      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
1993        /* Notification Type = NCI_DISCOVER_NTF_LAST or
1994         * NCI_DISCOVER_NTF_LAST_ABORT */
1995        if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE) {
1996          nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
1997        }
1998        nfa_dm_notify_discovery(p_data);
1999      }
2000      break;
2001    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2002      /*
2003      ** This is only for ISO15693.
2004      ** FW sends activation NTF when all responses are received from tags
2005      ** without host selecting.
2006      */
2007      nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
2008
2009      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2010          NFA_STATUS_FAILED) {
2011        NFA_TRACE_DEBUG0(
2012            "Not matched, restart discovery after receiving deactivate ntf");
2013
2014        /* after receiving deactivate event, restart discovery */
2015        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2016      }
2017      break;
2018    default:
2019      NFA_TRACE_ERROR0(
2020          "nfa_dm_disc_sm_w4_all_discoveries (): Unexpected discovery event");
2021      break;
2022  }
2023}
2024
2025/*******************************************************************************
2026**
2027** Function         nfa_dm_disc_sm_w4_host_select
2028**
2029** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT
2030**                  state
2031**
2032** Returns          void
2033**
2034*******************************************************************************/
2035static void nfa_dm_disc_sm_w4_host_select(tNFA_DM_RF_DISC_SM_EVENT event,
2036                                          tNFA_DM_RF_DISC_DATA* p_data) {
2037  tNFA_CONN_EVT_DATA conn_evt;
2038  tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
2039      (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2040  bool sleep_wakeup_event = false;
2041  bool sleep_wakeup_event_processed = false;
2042  tNFA_STATUS status;
2043
2044  switch (event) {
2045    case NFA_DM_RF_DISCOVER_SELECT_CMD:
2046      /* if not waiting to deactivate */
2047      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
2048        NFC_DiscoverySelect(p_data->select.rf_disc_id, p_data->select.protocol,
2049                            p_data->select.rf_interface);
2050      } else {
2051        nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
2052      }
2053      break;
2054
2055    case NFA_DM_RF_DISCOVER_SELECT_RSP:
2056      sleep_wakeup_event = true;
2057      /* notify application status of selection */
2058      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
2059        sleep_wakeup_event_processed = true;
2060        conn_evt.status = NFA_STATUS_OK;
2061        /* register callback to get interface error NTF */
2062        NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
2063      } else
2064        conn_evt.status = NFA_STATUS_FAILED;
2065
2066      if (!old_sleep_wakeup_flag) {
2067        nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT,
2068                                      p_data->nfc_discover.status);
2069      }
2070      break;
2071    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2072      nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
2073      /* always call nfa_dm_disc_notify_activation to update protocol/interface
2074       * information in NFA control blocks */
2075      status = nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
2076      if (old_sleep_wakeup_flag) {
2077        /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag;
2078         * if deactivation is pending then deactivate  */
2079        nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
2080      } else if (status == NFA_STATUS_FAILED) {
2081        NFA_TRACE_DEBUG0(
2082            "Not matched, restart discovery after receiving deactivate ntf");
2083
2084        /* after receiving deactivate event, restart discovery */
2085        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2086      }
2087      break;
2088    case NFA_DM_RF_DEACTIVATE_CMD:
2089      if (old_sleep_wakeup_flag) {
2090        nfa_dm_cb.disc_cb.deact_pending = true;
2091        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2092      }
2093      /* if deactivate CMD was not sent to NFCC */
2094      else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
2095        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
2096        /* only IDLE mode is allowed */
2097        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2098      }
2099      break;
2100    case NFA_DM_RF_DEACTIVATE_RSP:
2101      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2102      /* notify exiting from host select state */
2103      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2104                                      &(p_data->nfc_discover));
2105
2106      nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2107      nfa_dm_start_rf_discover();
2108      break;
2109
2110    case NFA_DM_CORE_INTF_ERROR_NTF:
2111      sleep_wakeup_event = true;
2112      if (!old_sleep_wakeup_flag) {
2113        /* target activation failed, upper layer may deactivate or select again
2114         */
2115        conn_evt.status = NFA_STATUS_FAILED;
2116        nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
2117      }
2118      break;
2119    default:
2120      NFA_TRACE_ERROR0(
2121          "nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
2122      break;
2123  }
2124
2125  if (old_sleep_wakeup_flag && sleep_wakeup_event &&
2126      !sleep_wakeup_event_processed) {
2127    /* performing sleep wakeup and exception conditions happened
2128     * clear sleep wakeup information and report failure */
2129    nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
2130  }
2131}
2132
2133/*******************************************************************************
2134**
2135** Function         nfa_dm_disc_sm_poll_active
2136**
2137** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
2138**
2139** Returns          void
2140**
2141*******************************************************************************/
2142static void nfa_dm_disc_sm_poll_active(tNFA_DM_RF_DISC_SM_EVENT event,
2143                                       tNFA_DM_RF_DISC_DATA* p_data) {
2144  tNFC_STATUS status;
2145  tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
2146      (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2147  bool sleep_wakeup_event = false;
2148  bool sleep_wakeup_event_processed = false;
2149  tNFC_DEACTIVATE_DEVT deact;
2150
2151  switch (event) {
2152    case NFA_DM_RF_DEACTIVATE_CMD:
2153      if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
2154        if ((nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_FRAME) &&
2155            (p_data->deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP)) {
2156          /* NCI 2.0- DH is responsible for sending deactivation commands before
2157           * RF_DEACTIVATE_CMD */
2158          nfa_dm_send_tag_deselect_cmd(nfa_dm_cb.disc_cb.activated_protocol);
2159        }
2160      }
2161
2162      if (nfa_dm_cb.disc_cb.activated_protocol == NCI_PROTOCOL_MIFARE) {
2163        nfa_dm_cb.disc_cb.deact_pending = true;
2164        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2165        status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2166        break;
2167      }
2168
2169      if (old_sleep_wakeup_flag) {
2170        /* sleep wakeup is already enabled when deactivate cmd is requested,
2171         * keep the information in control block to issue it later */
2172        nfa_dm_cb.disc_cb.deact_pending = true;
2173        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2174      } else {
2175        status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2176      }
2177
2178      break;
2179    case NFA_DM_RF_DEACTIVATE_RSP:
2180      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2181      /* register callback to get interface error NTF */
2182      NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
2183
2184      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2185        /* it's race condition. received deactivate NTF before receiving RSP */
2186
2187        deact.status = NFC_STATUS_OK;
2188        deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2189        deact.is_ntf = true;
2190        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2191                                        (tNFC_DISCOVER*)&deact);
2192
2193        /* NFCC is in IDLE state */
2194        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2195        nfa_dm_start_rf_discover();
2196      }
2197      break;
2198    case NFA_DM_RF_DEACTIVATE_NTF:
2199      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2200
2201      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2202
2203      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2204        /* it's race condition. received deactivate NTF before receiving RSP */
2205        /* notify deactivation after receiving deactivate RSP */
2206        NFA_TRACE_DEBUG0("Rx deactivate NTF while waiting for deactivate RSP");
2207        break;
2208      }
2209      if (p_data->nfc_discover.deactivate.reason !=
2210          NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2211        sleep_wakeup_event = true;
2212        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2213                                        &(p_data->nfc_discover));
2214        }
2215        if ((p_data->nfc_discover.deactivate.type ==
2216             NFC_DEACTIVATE_TYPE_SLEEP) ||
2217            (p_data->nfc_discover.deactivate.type ==
2218             NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
2219          if (p_data->nfc_discover.deactivate.reason !=
2220              NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2221            /* count for number of times deactivate cmd sent */
2222            nfa_dm_cb.deactivate_cmd_retry_count = 0;
2223          }
2224          nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
2225          if (old_sleep_wakeup_flag) {
2226            sleep_wakeup_event_processed = true;
2227            /* process pending deactivate request */
2228            if (nfa_dm_cb.disc_cb.deact_pending) {
2229              /* notify RW module that sleep wakeup is finished */
2230              /* if deactivation is pending then deactivate  */
2231              nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
2232
2233              /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will
2234               * not call this function */
2235              nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, true);
2236            } else {
2237              /* Successfully went to sleep mode for sleep wakeup */
2238              /* Now wake up the tag to complete the operation */
2239              NFC_DiscoverySelect(nfa_dm_cb.disc_cb.activated_rf_disc_id,
2240                                  nfa_dm_cb.disc_cb.activated_protocol,
2241                                  nfa_dm_cb.disc_cb.activated_rf_interface);
2242            }
2243          }
2244          if (p_data->nfc_discover.deactivate.reason ==
2245              NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
2246            /* in case deactivation is not sucessfull, NFCC shall send
2247               RF_DEACTIVATE_NTF with DH Req failed due to error.
2248               MW shall send deactivation cmd again for 3 three times. if
2249               deactivation is not successfull 3 times also,
2250               then MW shall send deacivate cmd with deactivate type is
2251               discovery */
2252            if (nfa_dm_cb.deactivate_cmd_retry_count == 3) {
2253              if ((!old_sleep_wakeup_flag) ||
2254                  (!nfa_dm_cb.disc_cb.deact_pending)) {
2255                nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2256              }
2257              nfa_dm_cb.deactivate_cmd_retry_count = 0;
2258            } else {
2259              nfa_dm_cb.deactivate_cmd_retry_count++;
2260              nfa_dm_send_deactivate_cmd(p_data->nfc_discover.deactivate.type);
2261            }
2262          }
2263      } else if (p_data->nfc_discover.deactivate.type ==
2264                 NFC_DEACTIVATE_TYPE_IDLE) {
2265        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2266        nfa_dm_start_rf_discover();
2267      } else if (p_data->nfc_discover.deactivate.type ==
2268                 NFC_DEACTIVATE_TYPE_DISCOVERY) {
2269        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2270        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
2271          /* stop discovery */
2272          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2273        }
2274      }
2275      break;
2276
2277    case NFA_DM_CORE_INTF_ERROR_NTF:
2278      sleep_wakeup_event = true;
2279      if ((!old_sleep_wakeup_flag) || (!nfa_dm_cb.disc_cb.deact_pending)) {
2280        nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2281      }
2282      break;
2283
2284    default:
2285      NFA_TRACE_ERROR0(
2286          "nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
2287      break;
2288  }
2289
2290  if (old_sleep_wakeup_flag && sleep_wakeup_event &&
2291      !sleep_wakeup_event_processed) {
2292    /* performing sleep wakeup and exception conditions happened
2293     * clear sleep wakeup information and report failure */
2294    nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
2295  }
2296}
2297
2298/*******************************************************************************
2299**
2300** Function         nfa_dm_disc_sm_listen_active
2301**
2302** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE
2303**                  state
2304**
2305** Returns          void
2306**
2307*******************************************************************************/
2308static void nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,
2309                                         tNFA_DM_RF_DISC_DATA* p_data) {
2310  tNFC_DEACTIVATE_DEVT deact;
2311
2312  switch (event) {
2313    case NFA_DM_RF_DEACTIVATE_CMD:
2314      nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2315      break;
2316    case NFA_DM_RF_DEACTIVATE_RSP:
2317      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2318      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2319        /* it's race condition. received deactivate NTF before receiving RSP */
2320
2321        deact.status = NFC_STATUS_OK;
2322        deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2323        deact.is_ntf = true;
2324        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2325                                        (tNFC_DISCOVER*)&deact);
2326
2327        /* NFCC is in IDLE state */
2328        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2329        nfa_dm_start_rf_discover();
2330      }
2331      break;
2332    case NFA_DM_RF_DEACTIVATE_NTF:
2333      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2334
2335      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2336
2337      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
2338        /* it's race condition. received deactivate NTF before receiving RSP */
2339        /* notify deactivation after receiving deactivate RSP */
2340        NFA_TRACE_DEBUG0("Rx deactivate NTF while waiting for deactivate RSP");
2341      } else {
2342        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2343                                        &(p_data->nfc_discover));
2344
2345        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
2346          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2347          nfa_dm_start_rf_discover();
2348        } else if ((p_data->nfc_discover.deactivate.type ==
2349                    NFC_DEACTIVATE_TYPE_SLEEP) ||
2350                   (p_data->nfc_discover.deactivate.type ==
2351                    NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
2352          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_SLEEP);
2353        } else if (p_data->nfc_discover.deactivate.type ==
2354                   NFC_DEACTIVATE_TYPE_DISCOVERY) {
2355          /* Discovery */
2356          nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2357          if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
2358            /* stop discovery */
2359            NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2360          }
2361        }
2362      }
2363      break;
2364
2365    case NFA_DM_CORE_INTF_ERROR_NTF:
2366      break;
2367    default:
2368      NFA_TRACE_ERROR0(
2369          "nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
2370      break;
2371  }
2372}
2373
2374/*******************************************************************************
2375**
2376** Function         nfa_dm_disc_sm_listen_sleep
2377**
2378** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP
2379**                  state
2380**
2381** Returns          void
2382**
2383*******************************************************************************/
2384static void nfa_dm_disc_sm_listen_sleep(tNFA_DM_RF_DISC_SM_EVENT event,
2385                                        tNFA_DM_RF_DISC_DATA* p_data) {
2386  switch (event) {
2387    case NFA_DM_RF_DEACTIVATE_CMD:
2388      nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2389
2390      /* if deactivate type is not discovery then NFCC will not sent
2391       * deactivation NTF */
2392      if (p_data->deactivate_type != NFA_DEACTIVATE_TYPE_DISCOVERY) {
2393        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2394        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2395      }
2396      break;
2397    case NFA_DM_RF_DEACTIVATE_RSP:
2398      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2399      /* if deactivate type in CMD was IDLE */
2400      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
2401        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2402                                        &(p_data->nfc_discover));
2403
2404        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2405        nfa_dm_start_rf_discover();
2406      }
2407      break;
2408    case NFA_DM_RF_DEACTIVATE_NTF:
2409      /* clear both W4_RSP and W4_NTF because of race condition between
2410       * deactivat CMD and link loss */
2411      nfa_dm_cb.disc_cb.disc_flags &=
2412          ~(NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
2413      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
2414
2415      /* there is no active protocol in this state, so broadcast to all by using
2416       * NFA_DM_RF_DEACTIVATE_RSP */
2417      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
2418                                      &(p_data->nfc_discover));
2419
2420      if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
2421        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2422        nfa_dm_start_rf_discover();
2423      } else if (p_data->nfc_discover.deactivate.type ==
2424                 NFA_DEACTIVATE_TYPE_DISCOVERY) {
2425        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
2426      } else {
2427        NFA_TRACE_ERROR0("Unexpected deactivation type");
2428        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
2429        nfa_dm_start_rf_discover();
2430      }
2431      break;
2432    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2433      nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
2434      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2435          NFA_STATUS_FAILED) {
2436        NFA_TRACE_DEBUG0(
2437            "Not matched, restart discovery after receiving deactivate ntf");
2438
2439        /* after receiving deactivate event, restart discovery */
2440        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
2441      }
2442      break;
2443    default:
2444      NFA_TRACE_ERROR0(
2445          "nfa_dm_disc_sm_listen_sleep (): Unexpected discovery event");
2446      break;
2447  }
2448}
2449
2450/*******************************************************************************
2451**
2452** Function         nfa_dm_disc_sm_lp_listen
2453**
2454** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
2455**
2456** Returns          void
2457**
2458*******************************************************************************/
2459static void nfa_dm_disc_sm_lp_listen(tNFA_DM_RF_DISC_SM_EVENT event,
2460                                     tNFA_DM_RF_DISC_DATA* p_data) {
2461  switch (event) {
2462    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2463      nfa_dm_disc_new_state(NFA_DM_RFST_LP_ACTIVE);
2464      nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
2465      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
2466          NFA_STATUS_FAILED) {
2467        NFA_TRACE_DEBUG0("Not matched, unexpected activation");
2468      }
2469      break;
2470
2471    default:
2472      NFA_TRACE_ERROR0(
2473          "nfa_dm_disc_sm_lp_listen (): Unexpected discovery event");
2474      break;
2475  }
2476}
2477
2478/*******************************************************************************
2479**
2480** Function         nfa_dm_disc_sm_lp_active
2481**
2482** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
2483**
2484** Returns          void
2485**
2486*******************************************************************************/
2487static void nfa_dm_disc_sm_lp_active(tNFA_DM_RF_DISC_SM_EVENT event,
2488                                     tNFA_DM_RF_DISC_DATA* p_data) {
2489  switch (event) {
2490    case NFA_DM_RF_DEACTIVATE_NTF:
2491      nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
2492      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
2493                                      &(p_data->nfc_discover));
2494      break;
2495    default:
2496      NFA_TRACE_ERROR0(
2497          "nfa_dm_disc_sm_lp_active (): Unexpected discovery event");
2498      break;
2499  }
2500}
2501
2502/*******************************************************************************
2503**
2504** Function         nfa_dm_disc_sm_execute
2505**
2506** Description      Processing discovery related events
2507**
2508** Returns          void
2509**
2510*******************************************************************************/
2511void nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,
2512                            tNFA_DM_RF_DISC_DATA* p_data) {
2513#if (BT_TRACE_VERBOSE == TRUE)
2514  NFA_TRACE_DEBUG5(
2515      "nfa_dm_disc_sm_execute (): state: %s (%d), event: %s(%d) disc_flags: "
2516      "0x%x",
2517      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
2518      nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_event_2_str(event), event,
2519      nfa_dm_cb.disc_cb.disc_flags);
2520#else
2521  NFA_TRACE_DEBUG3(
2522      "nfa_dm_disc_sm_execute(): state: %d, event:%d disc_flags: 0x%x",
2523      nfa_dm_cb.disc_cb.disc_state, event, nfa_dm_cb.disc_cb.disc_flags);
2524#endif
2525
2526  switch (nfa_dm_cb.disc_cb.disc_state) {
2527    /*  RF Discovery State - Idle */
2528    case NFA_DM_RFST_IDLE:
2529      nfa_dm_disc_sm_idle(event, p_data);
2530      break;
2531
2532    /* RF Discovery State - Discovery */
2533    case NFA_DM_RFST_DISCOVERY:
2534      nfa_dm_disc_sm_discovery(event, p_data);
2535      break;
2536
2537    /*RF Discovery State - Wait for all discoveries */
2538    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2539      nfa_dm_disc_sm_w4_all_discoveries(event, p_data);
2540      break;
2541
2542    /* RF Discovery State - Wait for host selection */
2543    case NFA_DM_RFST_W4_HOST_SELECT:
2544      nfa_dm_disc_sm_w4_host_select(event, p_data);
2545      break;
2546
2547    /* RF Discovery State - Poll mode activated */
2548    case NFA_DM_RFST_POLL_ACTIVE:
2549      nfa_dm_disc_sm_poll_active(event, p_data);
2550      break;
2551
2552    /* RF Discovery State - listen mode activated */
2553    case NFA_DM_RFST_LISTEN_ACTIVE:
2554      nfa_dm_disc_sm_listen_active(event, p_data);
2555      break;
2556
2557    /* RF Discovery State - listen mode sleep */
2558    case NFA_DM_RFST_LISTEN_SLEEP:
2559      nfa_dm_disc_sm_listen_sleep(event, p_data);
2560      break;
2561
2562    /* Listening in Low Power mode    */
2563    case NFA_DM_RFST_LP_LISTEN:
2564      nfa_dm_disc_sm_lp_listen(event, p_data);
2565      break;
2566
2567    /* Activated in Low Power mode    */
2568    case NFA_DM_RFST_LP_ACTIVE:
2569      nfa_dm_disc_sm_lp_active(event, p_data);
2570      break;
2571  }
2572#if (BT_TRACE_VERBOSE == TRUE)
2573  NFA_TRACE_DEBUG3(
2574      "nfa_dm_disc_sm_execute (): new state: %s (%d), disc_flags: 0x%x",
2575      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
2576      nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
2577#else
2578  NFA_TRACE_DEBUG2("nfa_dm_disc_sm_execute(): new state: %d,  disc_flags: 0x%x",
2579                   nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
2580#endif
2581}
2582
2583/*******************************************************************************
2584**
2585** Function         nfa_dm_add_rf_discover
2586**
2587** Description      Add discovery configuration and callback function
2588**
2589** Returns          valid handle if success
2590**
2591*******************************************************************************/
2592tNFA_HANDLE nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
2593                                   tNFA_DM_DISC_HOST_ID host_id,
2594                                   tNFA_DISCOVER_CBACK* p_disc_cback) {
2595  uint8_t xx;
2596
2597  NFA_TRACE_DEBUG1("nfa_dm_add_rf_discover () disc_mask=0x%x", disc_mask);
2598
2599  for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
2600    if (!nfa_dm_cb.disc_cb.entry[xx].in_use) {
2601      nfa_dm_cb.disc_cb.entry[xx].in_use = true;
2602      nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
2603      nfa_dm_cb.disc_cb.entry[xx].host_id = host_id;
2604      nfa_dm_cb.disc_cb.entry[xx].p_disc_cback = p_disc_cback;
2605      nfa_dm_cb.disc_cb.entry[xx].disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
2606      return xx;
2607    }
2608  }
2609
2610  return NFA_HANDLE_INVALID;
2611}
2612
2613/*******************************************************************************
2614**
2615** Function         nfa_dm_start_excl_discovery
2616**
2617** Description      Start exclusive RF discovery
2618**
2619** Returns          void
2620**
2621*******************************************************************************/
2622void nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,
2623                                 tNFA_LISTEN_CFG* p_listen_cfg,
2624                                 tNFA_DISCOVER_CBACK* p_disc_cback) {
2625  tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
2626
2627  NFA_TRACE_DEBUG0("nfa_dm_start_excl_discovery ()");
2628
2629  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
2630    poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
2631    poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
2632    poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
2633    poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
2634    poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
2635  }
2636  if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
2637    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE) {
2638      poll_disc_mask |= NFA_DM_DISC_MASK_PACM_NFC_DEP;
2639    }
2640  } else {
2641    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) {
2642      poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
2643    }
2644    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) {
2645      poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
2646    }
2647  }
2648
2649  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
2650    poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
2651  }
2652  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
2653    poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
2654    poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
2655  }
2656  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_V) {
2657    poll_disc_mask |= NFA_DM_DISC_MASK_P_T5T;
2658  }
2659  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
2660    poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
2661  }
2662  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
2663    poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
2664  }
2665
2666  nfa_dm_cb.disc_cb.excl_disc_entry.in_use = true;
2667  nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
2668  nfa_dm_cb.disc_cb.excl_disc_entry.host_id = NFA_DM_DISC_HOST_ID_DH;
2669  nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = p_disc_cback;
2670  nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
2671
2672  memcpy(&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg,
2673         sizeof(tNFA_LISTEN_CFG));
2674
2675  nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, NULL);
2676}
2677
2678/*******************************************************************************
2679**
2680** Function         nfa_dm_stop_excl_discovery
2681**
2682** Description      Stop exclusive RF discovery
2683**
2684** Returns          void
2685**
2686*******************************************************************************/
2687void nfa_dm_stop_excl_discovery(void) {
2688  NFA_TRACE_DEBUG0("nfa_dm_stop_excl_discovery ()");
2689
2690  nfa_dm_cb.disc_cb.excl_disc_entry.in_use = false;
2691  nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
2692}
2693
2694/*******************************************************************************
2695**
2696** Function         nfa_dm_delete_rf_discover
2697**
2698** Description      Remove discovery configuration and callback function
2699**
2700** Returns          void
2701**
2702*******************************************************************************/
2703void nfa_dm_delete_rf_discover(tNFA_HANDLE handle) {
2704  NFA_TRACE_DEBUG1("nfa_dm_delete_rf_discover () handle=0x%x", handle);
2705
2706  if (handle < NFA_DM_DISC_NUM_ENTRIES) {
2707    nfa_dm_cb.disc_cb.entry[handle].in_use = false;
2708  } else {
2709    NFA_TRACE_ERROR0("Invalid discovery handle");
2710  }
2711}
2712
2713/*******************************************************************************
2714**
2715** Function         nfa_dm_rf_discover_select
2716**
2717** Description      Select target, protocol and RF interface
2718**
2719** Returns          void
2720**
2721*******************************************************************************/
2722void nfa_dm_rf_discover_select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
2723                               tNFA_INTF_TYPE rf_interface) {
2724  tNFA_DM_DISC_SELECT_PARAMS select_params;
2725  tNFA_CONN_EVT_DATA conn_evt;
2726
2727  NFA_TRACE_DEBUG3(
2728      "nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
2729      rf_disc_id, protocol, rf_interface);
2730
2731  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
2732    /* state is OK: notify the status when the response is received from NFCC */
2733    select_params.rf_disc_id = rf_disc_id;
2734    select_params.protocol = protocol;
2735    select_params.rf_interface = rf_interface;
2736
2737    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
2738    nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_SELECT_CMD,
2739                           (tNFA_DM_RF_DISC_DATA*)&select_params);
2740  } else {
2741    /* Wrong state: notify failed status right away */
2742    conn_evt.status = NFA_STATUS_FAILED;
2743    nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
2744  }
2745}
2746
2747/*******************************************************************************
2748**
2749** Function         nfa_dm_rf_deactivate
2750**
2751** Description      Deactivate NFC link
2752**
2753** Returns          NFA_STATUS_OK if success
2754**
2755*******************************************************************************/
2756tNFA_STATUS nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type) {
2757  NFA_TRACE_DEBUG1("nfa_dm_rf_deactivate () deactivate_type:0x%X",
2758                   deactivate_type);
2759
2760  if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP) {
2761    if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
2762      deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
2763    else
2764      deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
2765  }
2766
2767  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
2768    return NFA_STATUS_FAILED;
2769  } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
2770    if (deactivate_type == NFA_DEACTIVATE_TYPE_DISCOVERY) {
2771      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
2772        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
2773        nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
2774        return NFA_STATUS_OK;
2775      } else {
2776        /* it could be race condition. */
2777        NFA_TRACE_DEBUG0("nfa_dm_rf_deactivate (): already in discovery state");
2778        return NFA_STATUS_FAILED;
2779      }
2780    } else if (deactivate_type == NFA_DEACTIVATE_TYPE_IDLE) {
2781      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
2782        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
2783        nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
2784      }
2785      nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
2786                             (tNFA_DM_RF_DISC_DATA*)&deactivate_type);
2787      return NFA_STATUS_OK;
2788    } else {
2789      return NFA_STATUS_FAILED;
2790    }
2791  } else {
2792    nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
2793                           (tNFA_DM_RF_DISC_DATA*)&deactivate_type);
2794    return NFA_STATUS_OK;
2795  }
2796}
2797
2798#if (BT_TRACE_VERBOSE == TRUE)
2799/*******************************************************************************
2800**
2801** Function         nfa_dm_disc_state_2_str
2802**
2803** Description      convert nfc discovery state to string
2804**
2805*******************************************************************************/
2806static char* nfa_dm_disc_state_2_str(uint8_t state) {
2807  switch (state) {
2808    case NFA_DM_RFST_IDLE:
2809      return "IDLE";
2810
2811    case NFA_DM_RFST_DISCOVERY:
2812      return "DISCOVERY";
2813
2814    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2815      return "W4_ALL_DISCOVERIES";
2816
2817    case NFA_DM_RFST_W4_HOST_SELECT:
2818      return "W4_HOST_SELECT";
2819
2820    case NFA_DM_RFST_POLL_ACTIVE:
2821      return "POLL_ACTIVE";
2822
2823    case NFA_DM_RFST_LISTEN_ACTIVE:
2824      return "LISTEN_ACTIVE";
2825
2826    case NFA_DM_RFST_LISTEN_SLEEP:
2827      return "LISTEN_SLEEP";
2828
2829    case NFA_DM_RFST_LP_LISTEN:
2830      return "LP_LISTEN";
2831
2832    case NFA_DM_RFST_LP_ACTIVE:
2833      return "LP_ACTIVE";
2834  }
2835  return "Unknown";
2836}
2837
2838/*******************************************************************************
2839**
2840** Function         nfa_dm_disc_event_2_str
2841**
2842** Description      convert nfc discovery RSP/NTF to string
2843**
2844*******************************************************************************/
2845static char* nfa_dm_disc_event_2_str(uint8_t event) {
2846  switch (event) {
2847    case NFA_DM_RF_DISCOVER_CMD:
2848      return "DISCOVER_CMD";
2849
2850    case NFA_DM_RF_DISCOVER_RSP:
2851      return "DISCOVER_RSP";
2852
2853    case NFA_DM_RF_DISCOVER_NTF:
2854      return "DISCOVER_NTF";
2855
2856    case NFA_DM_RF_DISCOVER_SELECT_CMD:
2857      return "SELECT_CMD";
2858
2859    case NFA_DM_RF_DISCOVER_SELECT_RSP:
2860      return "SELECT_RSP";
2861
2862    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2863      return "ACTIVATED_NTF";
2864
2865    case NFA_DM_RF_DEACTIVATE_CMD:
2866      return "DEACTIVATE_CMD";
2867
2868    case NFA_DM_RF_DEACTIVATE_RSP:
2869      return "DEACTIVATE_RSP";
2870
2871    case NFA_DM_RF_DEACTIVATE_NTF:
2872      return "DEACTIVATE_NTF";
2873
2874    case NFA_DM_LP_LISTEN_CMD:
2875      return "NFA_DM_LP_LISTEN_CMD";
2876
2877    case NFA_DM_CORE_INTF_ERROR_NTF:
2878      return "INTF_ERROR_NTF";
2879  }
2880  return "Unknown";
2881}
2882#endif /* BT_TRACE_VERBOSE */
2883
2884/*******************************************************************************
2885**
2886** Function         P2P_Prio_Logic
2887**
2888** Description      Implements algorithm for NFC-DEP protocol priority over
2889**                  ISO-DEP protocol.
2890**
2891** Returns          True if success
2892**
2893*******************************************************************************/
2894bool nfa_dm_p2p_prio_logic(uint8_t event, uint8_t* p, uint8_t event_type) {
2895  if (!nfa_poll_bail_out_mode) {
2896    NFA_TRACE_DEBUG0("p2p priority is running under bail out mode ONLY.");
2897    return true;
2898  }
2899
2900  if ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) &&
2901      (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED)) {
2902    NFA_TRACE_DEBUG0(
2903        "returning from nfa_dm_p2p_prio_logic  Disable p2p_prio_logic");
2904    return true;
2905  }
2906
2907  if (event == NCI_MSG_RF_DISCOVER &&
2908      p2p_prio_logic_data.timer_expired == true &&
2909      event_type == NFA_DM_P2P_PRIO_RSP) {
2910    NFA_TRACE_DEBUG0(
2911        "nfa_dm_p2p_prio_logic starting a timer for next rf intf activated "
2912        "ntf");
2913    nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
2914                          NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP,
2915                          ((uint32_t)nfa_dm_act_get_rf_disc_duration() *
2916                           QUICK_TIMER_TICKS_PER_SEC) /
2917                              1000);
2918    return true;
2919  }
2920
2921  if (event == NCI_MSG_RF_INTF_ACTIVATED &&
2922      p2p_prio_logic_data.timer_expired == true) {
2923    NFA_TRACE_DEBUG0(
2924        "nfa_dm_p2p_prio_logic stopping a timer for next rf intf activated "
2925        "ntf");
2926    nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
2927  }
2928
2929  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
2930    uint8_t rf_disc_id = 0xFF;
2931    uint8_t type = 0xFF;
2932    uint8_t protocol = 0xFF;
2933    uint8_t tech_mode = 0xFF;
2934
2935    NFA_TRACE_DEBUG0("P2P_Prio_Logic");
2936
2937    if (event == NCI_MSG_RF_INTF_ACTIVATED) {
2938      rf_disc_id = *p++;
2939      type = *p++;
2940      protocol = *p++;
2941      tech_mode = *p++;
2942    }
2943    NFA_TRACE_DEBUG1("nfa_dm_p2p_prio_logic event_type = 0x%x", event_type);
2944
2945    if (event == NCI_MSG_RF_INTF_ACTIVATED && tech_mode >= 0x80) {
2946      NFA_TRACE_DEBUG0(
2947          "nfa_dm_p2p_prio_logic listen mode activated reset all the "
2948          "nfa_dm_p2p_prio_logic variables ");
2949      nfa_dm_p2p_prio_logic_cleanup();
2950    }
2951
2952    if ((tech_mode < 0x80) && event == NCI_MSG_RF_INTF_ACTIVATED &&
2953        protocol == NCI_PROTOCOL_ISO_DEP &&
2954        p2p_prio_logic_data.isodep_detected == false) {
2955      nfa_dm_p2p_prio_logic_cleanup();
2956      p2p_prio_logic_data.isodep_detected = true;
2957      p2p_prio_logic_data.first_tech_mode = tech_mode;
2958      NFA_TRACE_DEBUG0("ISO-DEP Detected First Time  Resume the Polling Loop");
2959      nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2960      return false;
2961    }
2962
2963    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
2964             protocol == NCI_PROTOCOL_ISO_DEP &&
2965             p2p_prio_logic_data.isodep_detected == true &&
2966             p2p_prio_logic_data.first_tech_mode != tech_mode) {
2967      p2p_prio_logic_data.isodep_detected = true;
2968      p2p_prio_logic_data.timer_expired = false;
2969      NFA_TRACE_DEBUG0(
2970          "ISO-DEP Detected Second Time Other Techmode  Resume the Polling "
2971          "Loop");
2972      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
2973      nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
2974      return false;
2975    }
2976
2977    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
2978             protocol == NCI_PROTOCOL_ISO_DEP &&
2979             p2p_prio_logic_data.isodep_detected == true &&
2980             p2p_prio_logic_data.timer_expired == true) {
2981      NFA_TRACE_DEBUG0(
2982          "ISO-DEP Detected TimerExpired, Final Notifying the Event");
2983      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
2984      nfa_dm_p2p_prio_logic_cleanup();
2985    }
2986
2987    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
2988             protocol == NCI_PROTOCOL_ISO_DEP &&
2989             p2p_prio_logic_data.isodep_detected == true &&
2990             p2p_prio_logic_data.first_tech_mode == tech_mode) {
2991      NFA_TRACE_DEBUG0(
2992          "ISO-DEP Detected Same Techmode, Final Notifying the Event");
2993      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
2994      NFA_TRACE_DEBUG0("P2P_Stop_Timer");
2995      nfa_dm_p2p_prio_logic_cleanup();
2996    }
2997
2998    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
2999             protocol != NCI_PROTOCOL_ISO_DEP &&
3000             p2p_prio_logic_data.isodep_detected == true) {
3001      NFA_TRACE_DEBUG0(
3002          "ISO-DEP Not Detected  Giving Priority for other Technology");
3003      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
3004      NFA_TRACE_DEBUG0("P2P_Stop_Timer");
3005      nfa_dm_p2p_prio_logic_cleanup();
3006    }
3007
3008    else if (event == NCI_MSG_RF_DEACTIVATE &&
3009             p2p_prio_logic_data.isodep_detected == true &&
3010             p2p_prio_logic_data.timer_expired == false &&
3011             event_type == NFA_DM_P2P_PRIO_RSP) {
3012      NFA_TRACE_DEBUG0("NFA_DM_RF_DEACTIVATE_RSP");
3013      return false;
3014    }
3015
3016    else if (event == NCI_MSG_RF_DEACTIVATE &&
3017             p2p_prio_logic_data.isodep_detected == true &&
3018             p2p_prio_logic_data.timer_expired == false &&
3019             event_type == NFA_DM_P2P_PRIO_NTF) {
3020      NFA_TRACE_DEBUG0("NFA_DM_RF_DEACTIVATE_NTF");
3021
3022      nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
3023                            NFC_TTYPE_P2P_PRIO_RESPONSE,
3024                            ((uint32_t)160 * QUICK_TIMER_TICKS_PER_SEC) / 1000);
3025
3026      NFA_TRACE_DEBUG0("P2P_Start_Timer");
3027
3028      return false;
3029    }
3030  }
3031
3032  NFA_TRACE_DEBUG0("returning TRUE");
3033  return true;
3034}
3035
3036/*******************************************************************************
3037**
3038** Function         p2p_prio_logic_timeout
3039**
3040** Description      Callback function for p2p timer
3041**
3042** Returns          void
3043**
3044*******************************************************************************/
3045void nfa_dm_p2p_timer_event() {
3046  NFA_TRACE_DEBUG0("P2P_Timer_timeout NFC-DEP Not Discovered!!");
3047
3048  p2p_prio_logic_data.timer_expired = true;
3049
3050  if (p2p_prio_logic_data.isodep_detected == true) {
3051    NFA_TRACE_DEBUG0("Deactivate and Restart RF discovery");
3052    nci_snd_deactivate_cmd(NFC_DEACTIVATE_TYPE_IDLE);
3053  }
3054}
3055
3056/*******************************************************************************
3057**
3058** Function         nfa_dm_p2p_prio_logic_cleanup
3059**
3060** Description      Callback function for p2p prio logic cleanup timer
3061**
3062** Returns          void
3063**
3064*******************************************************************************/
3065void nfa_dm_p2p_prio_logic_cleanup() {
3066  memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
3067}
3068
3069/*******************************************************************************
3070**
3071** Function         nfa_dm_send_tag_deselect_cmd
3072**
3073** Description      Send command to send tag in sleep state
3074**
3075** Returns          void
3076**
3077*******************************************************************************/
3078static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol) {
3079  NFC_HDR* p_msg;
3080  uint8_t* p;
3081
3082  NFA_TRACE_DEBUG0("nfa_dm_send_tag_deselect_cmd");
3083  p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
3084
3085  if (p_msg) {
3086    if (protocol == NFC_PROTOCOL_ISO_DEP) {
3087      /* send one byte of 0xc2 as as deselect command to Tag */
3088      p_msg->len = 1;
3089      p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
3090      p = (uint8_t*)(p_msg + 1) + p_msg->offset;
3091      *p = NFA_RW_TAG_DESELECT_CMD;
3092    } else if (protocol == NFC_PROTOCOL_T2T) {
3093      p_msg->len = NFA_RW_TAG_SLP_REQ_LEN;
3094      p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
3095      p = (uint8_t*)(p_msg + 1) + p_msg->offset;
3096      memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, NFA_RW_TAG_SLP_REQ,
3097             p_msg->len);
3098    } else {
3099      GKI_freebuf(p_msg);
3100      return;
3101    }
3102    NFC_SendData(NFC_RF_CONN_ID, p_msg);
3103  }
3104}
3105