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