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