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