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