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