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