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    tNFA_STATUS         status;
2116
2117    switch (event)
2118    {
2119    case NFA_DM_RF_DISCOVER_SELECT_CMD:
2120        /* if not waiting to deactivate */
2121        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2122        {
2123            NFC_DiscoverySelect (p_data->select.rf_disc_id,
2124                                 p_data->select.protocol,
2125                                 p_data->select.rf_interface);
2126        }
2127        else
2128        {
2129            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
2130        }
2131        break;
2132
2133    case NFA_DM_RF_DISCOVER_SELECT_RSP:
2134        sleep_wakeup_event = TRUE;
2135        /* notify application status of selection */
2136        if (p_data->nfc_discover.status == NFC_STATUS_OK)
2137        {
2138            sleep_wakeup_event_processed = TRUE;
2139            conn_evt.status = NFA_STATUS_OK;
2140            /* register callback to get interface error NTF */
2141            NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
2142        }
2143        else
2144            conn_evt.status = NFA_STATUS_FAILED;
2145
2146        if (!old_sleep_wakeup_flag)
2147        {
2148            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, p_data->nfc_discover.status);
2149        }
2150        break;
2151    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2152        nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
2153        /* always call nfa_dm_disc_notify_activation to update protocol/interface information in NFA control blocks */
2154        status = nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
2155        if (old_sleep_wakeup_flag)
2156        {
2157            /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag; if deactivation is pending then deactivate  */
2158            nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_OK);
2159        }
2160        else if (status == NFA_STATUS_FAILED)
2161        {
2162            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
2163
2164            /* after receiving deactivate event, restart discovery */
2165            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2166        }
2167        break;
2168    case NFA_DM_RF_DEACTIVATE_CMD:
2169        if (old_sleep_wakeup_flag)
2170        {
2171            nfa_dm_cb.disc_cb.deact_pending      = TRUE;
2172            nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2173        }
2174        /* if deactivate CMD was not sent to NFCC */
2175        else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2176        {
2177            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
2178            /* only IDLE mode is allowed */
2179            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2180        }
2181        break;
2182    case NFA_DM_RF_DEACTIVATE_RSP:
2183        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2184        /* notify exiting from host select state */
2185        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
2186
2187        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2188        nfa_dm_start_rf_discover ();
2189        break;
2190
2191    case NFA_DM_CORE_INTF_ERROR_NTF:
2192        sleep_wakeup_event    = TRUE;
2193        if (!old_sleep_wakeup_flag)
2194        {
2195            /* target activation failed, upper layer may deactivate or select again */
2196            conn_evt.status = NFA_STATUS_FAILED;
2197            nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
2198        }
2199        break;
2200    default:
2201        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
2202        break;
2203    }
2204
2205    if (old_sleep_wakeup_flag && sleep_wakeup_event && !sleep_wakeup_event_processed)
2206    {
2207        /* performing sleep wakeup and exception conditions happened
2208         * clear sleep wakeup information and report failure */
2209        nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_FAILED);
2210    }
2211}
2212
2213/*******************************************************************************
2214**
2215** Function         nfa_dm_disc_sm_poll_active
2216**
2217** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
2218**
2219** Returns          void
2220**
2221*******************************************************************************/
2222static void nfa_dm_disc_sm_poll_active (tNFA_DM_RF_DISC_SM_EVENT event,
2223                                        tNFA_DM_RF_DISC_DATA *p_data)
2224{
2225    tNFC_STATUS status;
2226    tNFA_DM_DISC_FLAGS  old_sleep_wakeup_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2227    BOOLEAN             sleep_wakeup_event = FALSE;
2228    BOOLEAN             sleep_wakeup_event_processed = FALSE;
2229    tNFC_DEACTIVATE_DEVT deact;
2230
2231    switch (event)
2232    {
2233    case NFA_DM_RF_DEACTIVATE_CMD:
2234        if (old_sleep_wakeup_flag)
2235        {
2236            /* sleep wakeup is already enabled when deactivate cmd is requested,
2237             * keep the information in control block to issue it later */
2238            nfa_dm_cb.disc_cb.deact_pending      = TRUE;
2239            nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2240        }
2241        else
2242        {
2243            status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2244        }
2245
2246        break;
2247    case NFA_DM_RF_DEACTIVATE_RSP:
2248        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2249        /* register callback to get interface error NTF */
2250        NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
2251
2252        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
2253        {
2254            /* it's race condition. received deactivate NTF before receiving RSP */
2255
2256            deact.status = NFC_STATUS_OK;
2257            deact.type   = NFC_DEACTIVATE_TYPE_IDLE;
2258            deact.is_ntf = TRUE;
2259            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, (tNFC_DISCOVER*)&deact);
2260
2261            /* NFCC is in IDLE state */
2262            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2263            nfa_dm_start_rf_discover ();
2264        }
2265        break;
2266    case NFA_DM_RF_DEACTIVATE_NTF:
2267        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2268
2269        nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2270
2271        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
2272        {
2273            /* it's race condition. received deactivate NTF before receiving RSP */
2274            /* notify deactivation after receiving deactivate RSP */
2275            NFA_TRACE_DEBUG0 ("Rx deactivate NTF while waiting for deactivate RSP");
2276            break;
2277        }
2278
2279        sleep_wakeup_event    = TRUE;
2280
2281        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2282
2283        if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
2284            ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
2285        {
2286            nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
2287            if (old_sleep_wakeup_flag)
2288            {
2289                sleep_wakeup_event_processed  = TRUE;
2290                /* process pending deactivate request */
2291                if (nfa_dm_cb.disc_cb.deact_pending)
2292                {
2293                    /* notify RW module that sleep wakeup is finished */
2294                    /* if deactivation is pending then deactivate  */
2295                    nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_OK);
2296
2297                    /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will not call this function */
2298                    nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, TRUE);
2299                }
2300                else
2301                {
2302                    /* Successfully went to sleep mode for sleep wakeup */
2303                    /* Now wake up the tag to complete the operation */
2304                    NFC_DiscoverySelect (nfa_dm_cb.disc_cb.activated_rf_disc_id,
2305                                         nfa_dm_cb.disc_cb.activated_protocol,
2306                                         nfa_dm_cb.disc_cb.activated_rf_interface);
2307                }
2308
2309            }
2310        }
2311        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
2312        {
2313            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2314            nfa_dm_start_rf_discover ();
2315        }
2316        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
2317        {
2318            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
2319            if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
2320            {
2321                /* stop discovery */
2322                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2323            }
2324        }
2325        break;
2326
2327    case NFA_DM_CORE_INTF_ERROR_NTF:
2328        sleep_wakeup_event    = TRUE;
2329        if (  (!old_sleep_wakeup_flag)
2330            ||(!nfa_dm_cb.disc_cb.deact_pending)  )
2331        {
2332            nfa_dm_send_deactivate_cmd (NFA_DEACTIVATE_TYPE_DISCOVERY);
2333        }
2334        break;
2335
2336    default:
2337        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
2338        break;
2339    }
2340
2341    if (old_sleep_wakeup_flag && sleep_wakeup_event && !sleep_wakeup_event_processed)
2342    {
2343        /* performing sleep wakeup and exception conditions happened
2344         * clear sleep wakeup information and report failure */
2345        nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_FAILED);
2346    }
2347}
2348
2349/*******************************************************************************
2350**
2351** Function         nfa_dm_disc_sm_listen_active
2352**
2353** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE state
2354**
2355** Returns          void
2356**
2357*******************************************************************************/
2358static void nfa_dm_disc_sm_listen_active (tNFA_DM_RF_DISC_SM_EVENT event,
2359                                          tNFA_DM_RF_DISC_DATA     *p_data)
2360{
2361    tNFC_DEACTIVATE_DEVT deact;
2362
2363    switch (event)
2364    {
2365    case NFA_DM_RF_DEACTIVATE_CMD:
2366        nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2367        break;
2368    case NFA_DM_RF_DEACTIVATE_RSP:
2369        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2370        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
2371        {
2372            /* it's race condition. received deactivate NTF before receiving RSP */
2373
2374            deact.status = NFC_STATUS_OK;
2375            deact.type   = NFC_DEACTIVATE_TYPE_IDLE;
2376            deact.is_ntf = TRUE;
2377            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, (tNFC_DISCOVER*)&deact);
2378
2379            /* NFCC is in IDLE state */
2380            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2381            nfa_dm_start_rf_discover ();
2382        }
2383        break;
2384    case NFA_DM_RF_DEACTIVATE_NTF:
2385        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2386
2387        nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2388
2389        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
2390        {
2391            /* it's race condition. received deactivate NTF before receiving RSP */
2392            /* notify deactivation after receiving deactivate RSP */
2393            NFA_TRACE_DEBUG0 ("Rx deactivate NTF while waiting for deactivate RSP");
2394        }
2395        else
2396        {
2397            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2398
2399            if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
2400            {
2401                nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2402                nfa_dm_start_rf_discover ();
2403            }
2404            else if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
2405                     ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
2406            {
2407                nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_SLEEP);
2408            }
2409            else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
2410            {
2411                /* Discovery */
2412                nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
2413                if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
2414                {
2415                    /* stop discovery */
2416                    NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2417                }
2418            }
2419        }
2420        break;
2421
2422    case NFA_DM_CORE_INTF_ERROR_NTF:
2423        break;
2424    default:
2425        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
2426        break;
2427    }
2428}
2429
2430/*******************************************************************************
2431**
2432** Function         nfa_dm_disc_sm_listen_sleep
2433**
2434** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP state
2435**
2436** Returns          void
2437**
2438*******************************************************************************/
2439static void nfa_dm_disc_sm_listen_sleep (tNFA_DM_RF_DISC_SM_EVENT event,
2440                                         tNFA_DM_RF_DISC_DATA *p_data)
2441{
2442    switch (event)
2443    {
2444    case NFA_DM_RF_DEACTIVATE_CMD:
2445        nfa_dm_send_deactivate_cmd (p_data->deactivate_type);
2446
2447        /* if deactivate type is not discovery then NFCC will not sent deactivation NTF */
2448        if (p_data->deactivate_type != NFA_DEACTIVATE_TYPE_DISCOVERY)
2449        {
2450            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2451            nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2452        }
2453        break;
2454    case NFA_DM_RF_DEACTIVATE_RSP:
2455        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2456        /* if deactivate type in CMD was IDLE */
2457        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
2458        {
2459            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
2460
2461            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2462            nfa_dm_start_rf_discover ();
2463        }
2464        break;
2465    case NFA_DM_RF_DEACTIVATE_NTF:
2466        /* clear both W4_RSP and W4_NTF because of race condition between deactivat CMD and link loss */
2467        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
2468        nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2469
2470        /* there is no active protocol in this state, so broadcast to all by using NFA_DM_RF_DEACTIVATE_RSP */
2471        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
2472
2473        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
2474        {
2475            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2476            nfa_dm_start_rf_discover ();
2477        }
2478        else if (p_data->nfc_discover.deactivate.type == NFA_DEACTIVATE_TYPE_DISCOVERY)
2479        {
2480            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
2481        }
2482        else
2483        {
2484            NFA_TRACE_ERROR0 ("Unexpected deactivation type");
2485            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2486            nfa_dm_start_rf_discover ();
2487        }
2488        break;
2489    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2490        nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
2491        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
2492        {
2493            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
2494
2495            /* after receiving deactivate event, restart discovery */
2496            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2497        }
2498        break;
2499    default:
2500        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_sleep (): Unexpected discovery event");
2501        break;
2502    }
2503}
2504
2505/*******************************************************************************
2506**
2507** Function         nfa_dm_disc_sm_lp_listen
2508**
2509** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
2510**
2511** Returns          void
2512**
2513*******************************************************************************/
2514static void nfa_dm_disc_sm_lp_listen (tNFA_DM_RF_DISC_SM_EVENT event,
2515                                           tNFA_DM_RF_DISC_DATA *p_data)
2516{
2517    switch (event)
2518    {
2519    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2520        nfa_dm_disc_new_state (NFA_DM_RFST_LP_ACTIVE);
2521        nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
2522        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
2523        {
2524            NFA_TRACE_DEBUG0 ("Not matched, unexpected activation");
2525        }
2526        break;
2527
2528    default:
2529        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_listen (): Unexpected discovery event");
2530        break;
2531    }
2532}
2533
2534/*******************************************************************************
2535**
2536** Function         nfa_dm_disc_sm_lp_active
2537**
2538** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
2539**
2540** Returns          void
2541**
2542*******************************************************************************/
2543static void nfa_dm_disc_sm_lp_active (tNFA_DM_RF_DISC_SM_EVENT event,
2544                                           tNFA_DM_RF_DISC_DATA *p_data)
2545{
2546    switch (event)
2547    {
2548    case NFA_DM_RF_DEACTIVATE_NTF:
2549        nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
2550        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2551        break;
2552    default:
2553        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_active (): Unexpected discovery event");
2554        break;
2555    }
2556}
2557
2558/*******************************************************************************
2559**
2560** Function         nfa_dm_disc_sm_execute
2561**
2562** Description      Processing discovery related events
2563**
2564** Returns          void
2565**
2566*******************************************************************************/
2567void nfa_dm_disc_sm_execute (tNFA_DM_RF_DISC_SM_EVENT event, tNFA_DM_RF_DISC_DATA *p_data)
2568{
2569#if (BT_TRACE_VERBOSE == TRUE)
2570    NFA_TRACE_DEBUG5 ("nfa_dm_disc_sm_execute (): state: %s (%d), event: %s(%d) disc_flags: 0x%x",
2571                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
2572                       nfa_dm_disc_event_2_str (event), event, nfa_dm_cb.disc_cb.disc_flags);
2573#else
2574    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute(): state: %d, event:%d disc_flags: 0x%x",
2575                       nfa_dm_cb.disc_cb.disc_state, event, nfa_dm_cb.disc_cb.disc_flags);
2576#endif
2577
2578    switch (nfa_dm_cb.disc_cb.disc_state)
2579    {
2580    /*  RF Discovery State - Idle */
2581    case NFA_DM_RFST_IDLE:
2582        nfa_dm_disc_sm_idle (event, p_data);
2583        break;
2584
2585    /* RF Discovery State - Discovery */
2586    case NFA_DM_RFST_DISCOVERY:
2587        nfa_dm_disc_sm_discovery (event, p_data);
2588        break;
2589
2590    /*RF Discovery State - Wait for all discoveries */
2591    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2592        nfa_dm_disc_sm_w4_all_discoveries (event, p_data);
2593        break;
2594
2595    /* RF Discovery State - Wait for host selection */
2596    case NFA_DM_RFST_W4_HOST_SELECT:
2597        nfa_dm_disc_sm_w4_host_select (event, p_data);
2598        break;
2599
2600    /* RF Discovery State - Poll mode activated */
2601    case NFA_DM_RFST_POLL_ACTIVE:
2602        nfa_dm_disc_sm_poll_active (event, p_data);
2603        break;
2604
2605    /* RF Discovery State - listen mode activated */
2606    case NFA_DM_RFST_LISTEN_ACTIVE:
2607        nfa_dm_disc_sm_listen_active (event, p_data);
2608        break;
2609
2610    /* RF Discovery State - listen mode sleep */
2611    case NFA_DM_RFST_LISTEN_SLEEP:
2612        nfa_dm_disc_sm_listen_sleep (event, p_data);
2613        break;
2614
2615    /* Listening in Low Power mode    */
2616    case NFA_DM_RFST_LP_LISTEN:
2617        nfa_dm_disc_sm_lp_listen (event, p_data);
2618        break;
2619
2620    /* Activated in Low Power mode    */
2621    case NFA_DM_RFST_LP_ACTIVE:
2622        nfa_dm_disc_sm_lp_active (event, p_data);
2623        break;
2624    }
2625#if (BT_TRACE_VERBOSE == TRUE)
2626    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute (): new state: %s (%d), disc_flags: 0x%x",
2627                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
2628                       nfa_dm_cb.disc_cb.disc_flags);
2629#else
2630    NFA_TRACE_DEBUG2 ("nfa_dm_disc_sm_execute(): new state: %d,  disc_flags: 0x%x",
2631                       nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
2632#endif
2633}
2634
2635/*******************************************************************************
2636**
2637** Function         nfa_dm_add_rf_discover
2638**
2639** Description      Add discovery configuration and callback function
2640**
2641** Returns          valid handle if success
2642**
2643*******************************************************************************/
2644tNFA_HANDLE nfa_dm_add_rf_discover (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
2645                                    tNFA_DM_DISC_HOST_ID         host_id,
2646                                    tNFA_DISCOVER_CBACK         *p_disc_cback)
2647{
2648    UINT8       xx;
2649
2650    NFA_TRACE_DEBUG1 ("nfa_dm_add_rf_discover () disc_mask=0x%x", disc_mask);
2651
2652    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
2653    {
2654        if (!nfa_dm_cb.disc_cb.entry[xx].in_use)
2655        {
2656            nfa_dm_cb.disc_cb.entry[xx].in_use              = TRUE;
2657            nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
2658            nfa_dm_cb.disc_cb.entry[xx].host_id             = host_id;
2659            nfa_dm_cb.disc_cb.entry[xx].p_disc_cback        = p_disc_cback;
2660            nfa_dm_cb.disc_cb.entry[xx].disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
2661            return xx;
2662        }
2663    }
2664
2665    return NFA_HANDLE_INVALID;
2666}
2667
2668/*******************************************************************************
2669**
2670** Function         nfa_dm_start_excl_discovery
2671**
2672** Description      Start exclusive RF discovery
2673**
2674** Returns          void
2675**
2676*******************************************************************************/
2677void nfa_dm_start_excl_discovery (tNFA_TECHNOLOGY_MASK poll_tech_mask,
2678                                  tNFA_LISTEN_CFG *p_listen_cfg,
2679                                  tNFA_DISCOVER_CBACK  *p_disc_cback)
2680{
2681    tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
2682
2683    NFA_TRACE_DEBUG0 ("nfa_dm_start_excl_discovery ()");
2684
2685    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A)
2686    {
2687        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
2688        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
2689        poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
2690        poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
2691        poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
2692    }
2693    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
2694    {
2695        poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
2696    }
2697    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B)
2698    {
2699        poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
2700    }
2701    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
2702    {
2703        poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
2704        poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
2705    }
2706    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
2707    {
2708        poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
2709    }
2710    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
2711    {
2712        poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
2713    }
2714    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
2715    {
2716        poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
2717    }
2718    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
2719    {
2720        poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
2721    }
2722
2723    nfa_dm_cb.disc_cb.excl_disc_entry.in_use              = TRUE;
2724    nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
2725    nfa_dm_cb.disc_cb.excl_disc_entry.host_id             = NFA_DM_DISC_HOST_ID_DH;
2726    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback        = p_disc_cback;
2727    nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
2728
2729    memcpy (&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg, sizeof (tNFA_LISTEN_CFG));
2730
2731    nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_CMD, NULL);
2732}
2733
2734/*******************************************************************************
2735**
2736** Function         nfa_dm_stop_excl_discovery
2737**
2738** Description      Stop exclusive RF discovery
2739**
2740** Returns          void
2741**
2742*******************************************************************************/
2743void nfa_dm_stop_excl_discovery (void)
2744{
2745    NFA_TRACE_DEBUG0 ("nfa_dm_stop_excl_discovery ()");
2746
2747    nfa_dm_cb.disc_cb.excl_disc_entry.in_use       = FALSE;
2748    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
2749}
2750
2751/*******************************************************************************
2752**
2753** Function         nfa_dm_delete_rf_discover
2754**
2755** Description      Remove discovery configuration and callback function
2756**
2757** Returns          void
2758**
2759*******************************************************************************/
2760void nfa_dm_delete_rf_discover (tNFA_HANDLE handle)
2761{
2762    NFA_TRACE_DEBUG1 ("nfa_dm_delete_rf_discover () handle=0x%x", handle);
2763
2764    if (handle < NFA_DM_DISC_NUM_ENTRIES)
2765    {
2766        nfa_dm_cb.disc_cb.entry[handle].in_use = FALSE;
2767    }
2768    else
2769    {
2770        NFA_TRACE_ERROR0 ("Invalid discovery handle");
2771    }
2772}
2773
2774/*******************************************************************************
2775**
2776** Function         nfa_dm_rf_discover_select
2777**
2778** Description      Select target, protocol and RF interface
2779**
2780** Returns          void
2781**
2782*******************************************************************************/
2783void nfa_dm_rf_discover_select (UINT8             rf_disc_id,
2784                                       tNFA_NFC_PROTOCOL protocol,
2785                                       tNFA_INTF_TYPE    rf_interface)
2786{
2787    tNFA_DM_DISC_SELECT_PARAMS select_params;
2788    tNFA_CONN_EVT_DATA conn_evt;
2789
2790    NFA_TRACE_DEBUG3 ("nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
2791                       rf_disc_id, protocol, rf_interface);
2792
2793    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
2794    {
2795        /* state is OK: notify the status when the response is received from NFCC */
2796        select_params.rf_disc_id   = rf_disc_id;
2797        select_params.protocol     = protocol;
2798        select_params.rf_interface = rf_interface;
2799
2800        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
2801        nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_SELECT_CMD, (tNFA_DM_RF_DISC_DATA *) &select_params);
2802    }
2803    else
2804    {
2805        /* Wrong state: notify failed status right away */
2806        conn_evt.status = NFA_STATUS_FAILED;
2807        nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
2808    }
2809}
2810
2811/*******************************************************************************
2812**
2813** Function         nfa_dm_rf_deactivate
2814**
2815** Description      Deactivate NFC link
2816**
2817** Returns          NFA_STATUS_OK if success
2818**
2819*******************************************************************************/
2820tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type)
2821{
2822    NFA_TRACE_DEBUG1 ("nfa_dm_rf_deactivate () deactivate_type:0x%X", deactivate_type);
2823
2824    if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP)
2825    {
2826        if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
2827            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
2828        else
2829            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
2830    }
2831
2832    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
2833    {
2834        return NFA_STATUS_FAILED;
2835    }
2836    else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY)
2837    {
2838        if (deactivate_type == NFA_DEACTIVATE_TYPE_DISCOVERY)
2839        {
2840            if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
2841            {
2842                nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.kovio_tle);
2843                nfa_dm_disc_kovio_timeout_cback (&nfa_dm_cb.disc_cb.kovio_tle);
2844                return NFA_STATUS_OK;
2845            }
2846            else
2847            {
2848                /* it could be race condition. */
2849                NFA_TRACE_DEBUG0 ("nfa_dm_rf_deactivate (): already in discovery state");
2850                return NFA_STATUS_FAILED;
2851            }
2852        }
2853        else if (deactivate_type == NFA_DEACTIVATE_TYPE_IDLE)
2854        {
2855            if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
2856            {
2857                nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.kovio_tle);
2858                nfa_dm_disc_kovio_timeout_cback (&nfa_dm_cb.disc_cb.kovio_tle);
2859            }
2860            nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
2861            return NFA_STATUS_OK;
2862        }
2863        else
2864        {
2865            return NFA_STATUS_FAILED;
2866        }
2867    }
2868    else
2869    {
2870        nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
2871        return NFA_STATUS_OK;
2872    }
2873}
2874
2875#if (BT_TRACE_VERBOSE == TRUE)
2876/*******************************************************************************
2877**
2878** Function         nfa_dm_disc_state_2_str
2879**
2880** Description      convert nfc discovery state to string
2881**
2882*******************************************************************************/
2883static char *nfa_dm_disc_state_2_str (UINT8 state)
2884{
2885    switch (state)
2886    {
2887    case NFA_DM_RFST_IDLE:
2888        return "IDLE";
2889
2890    case NFA_DM_RFST_DISCOVERY:
2891        return "DISCOVERY";
2892
2893    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2894        return "W4_ALL_DISCOVERIES";
2895
2896    case NFA_DM_RFST_W4_HOST_SELECT:
2897        return "W4_HOST_SELECT";
2898
2899    case NFA_DM_RFST_POLL_ACTIVE:
2900        return "POLL_ACTIVE";
2901
2902    case NFA_DM_RFST_LISTEN_ACTIVE:
2903        return "LISTEN_ACTIVE";
2904
2905    case NFA_DM_RFST_LISTEN_SLEEP:
2906        return "LISTEN_SLEEP";
2907
2908    case NFA_DM_RFST_LP_LISTEN:
2909        return "LP_LISTEN";
2910
2911    case NFA_DM_RFST_LP_ACTIVE:
2912        return "LP_ACTIVE";
2913    }
2914    return "Unknown";
2915}
2916
2917/*******************************************************************************
2918**
2919** Function         nfa_dm_disc_event_2_str
2920**
2921** Description      convert nfc discovery RSP/NTF to string
2922**
2923*******************************************************************************/
2924static char *nfa_dm_disc_event_2_str (UINT8 event)
2925{
2926    switch (event)
2927    {
2928    case NFA_DM_RF_DISCOVER_CMD:
2929        return "DISCOVER_CMD";
2930
2931    case NFA_DM_RF_DISCOVER_RSP:
2932        return "DISCOVER_RSP";
2933
2934    case NFA_DM_RF_DISCOVER_NTF:
2935        return "DISCOVER_NTF";
2936
2937    case NFA_DM_RF_DISCOVER_SELECT_CMD:
2938        return "SELECT_CMD";
2939
2940    case NFA_DM_RF_DISCOVER_SELECT_RSP:
2941        return "SELECT_RSP";
2942
2943    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2944        return "ACTIVATED_NTF";
2945
2946    case NFA_DM_RF_DEACTIVATE_CMD:
2947        return "DEACTIVATE_CMD";
2948
2949    case NFA_DM_RF_DEACTIVATE_RSP:
2950        return "DEACTIVATE_RSP";
2951
2952    case NFA_DM_RF_DEACTIVATE_NTF:
2953        return "DEACTIVATE_NTF";
2954
2955    case NFA_DM_LP_LISTEN_CMD:
2956        return "NFA_DM_LP_LISTEN_CMD";
2957
2958    case NFA_DM_CORE_INTF_ERROR_NTF:
2959        return "INTF_ERROR_NTF";
2960
2961    }
2962    return "Unknown";
2963}
2964#endif /* BT_TRACE_VERBOSE */
2965