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