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