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