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