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