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