nfa_dm_discover.c revision 85b7e84f6cc61506c94e98844cac9ce50bbbe9dc
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2013 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  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
939                    /* host can listen NFC-DEP based on protocol routing */
940                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LA_NFC_DEP);
941                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LAA_NFC_DEP);
942                }
943
944                /* NFC-B */
945                /* multiple hosts can listen ISO-DEP based on AID routing */
946                listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
947                               & NFA_DM_DISC_MASK_LB_ISO_DEP;
948
949                /* NFC-F */
950                if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F])
951                {
952                    listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
953                                   & ( NFA_DM_DISC_MASK_LF_T3T
954                                      |NFA_DM_DISC_MASK_LF_NFC_DEP
955                                      |NFA_DM_DISC_MASK_LFA_NFC_DEP );
956                }
957                else
958                {
959                    /* NFCC can listen T3T based on NFCID routing */
960                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LF_T3T);
961                }
962
963                /* NFC-B Prime */
964                if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP])
965                {
966                    listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
967                                   & NFA_DM_DISC_MASK_L_B_PRIME;
968                }
969
970                /*
971                ** clear listen mode technolgies and protocols which are already used by others
972                */
973
974                /* Check if other modules are listening T1T or T2T */
975                if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T))
976                {
977                    listen_mask &= ~( NFA_DM_DISC_MASK_LA_T1T
978                                     |NFA_DM_DISC_MASK_LA_T2T
979                                     |NFA_DM_DISC_MASK_LA_ISO_DEP
980                                     |NFA_DM_DISC_MASK_LA_NFC_DEP );
981                }
982
983                /* T1T/T2T has priority on NFC-A */
984                if (  (dm_disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP))
985                    &&(listen_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T)))
986                {
987                    dm_disc_mask &= ~( NFA_DM_DISC_MASK_LA_ISO_DEP
988                                      |NFA_DM_DISC_MASK_LA_NFC_DEP );
989                }
990
991                /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based on AID routing */
992
993                /* Check if other modules are listening NFC-DEP */
994                if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP))
995                {
996                    listen_mask &= ~( NFA_DM_DISC_MASK_LA_NFC_DEP
997                                     |NFA_DM_DISC_MASK_LAA_NFC_DEP );
998                }
999
1000                nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask = poll_mask | listen_mask;
1001
1002                NFA_TRACE_DEBUG2 ("nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x",
1003                                   xx, nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
1004
1005                dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
1006            }
1007        }
1008
1009        /* Let P2P set GEN bytes for LLCP to NFCC */
1010        if (dm_disc_mask & ( NFA_DM_DISC_MASK_PA_NFC_DEP
1011                            |NFA_DM_DISC_MASK_PF_NFC_DEP
1012                            |NFA_DM_DISC_MASK_LA_NFC_DEP
1013                            |NFA_DM_DISC_MASK_LF_NFC_DEP
1014                            |NFA_DM_DISC_MASK_PAA_NFC_DEP
1015                            |NFA_DM_DISC_MASK_PFA_NFC_DEP
1016                            |NFA_DM_DISC_MASK_LAA_NFC_DEP
1017                            |NFA_DM_DISC_MASK_LFA_NFC_DEP ))
1018        {
1019            nfa_p2p_set_config (dm_disc_mask);
1020        }
1021    }
1022
1023    NFA_TRACE_DEBUG1 ("dm_disc_mask = 0x%x", dm_disc_mask);
1024
1025    /* Get Discovery Technology parameters */
1026    num_params = nfa_dm_get_rf_discover_config (dm_disc_mask, disc_params, NFA_DM_MAX_DISC_PARAMS);
1027
1028    if (num_params)
1029    {
1030        /*
1031        ** NFCC will abort programming personality slots if not available.
1032        ** NFCC programs the personality slots in the following order of RF technologies:
1033        **      NFC-A, NFC-B, NFC-BP, NFC-I93
1034        */
1035
1036        /* if this is not for exclusive control */
1037        if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1038        {
1039            /* update listening protocols in each NFC technology */
1040            nfa_dm_set_rf_listen_mode_config (dm_disc_mask);
1041        }
1042
1043        /* Set polling duty cycle */
1044        nfa_dm_set_total_duration ();
1045        nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
1046
1047        NFC_DiscoveryStart (num_params, disc_params, nfa_dm_disc_discovery_cback);
1048        /* set flag about waiting for response in IDLE state */
1049        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1050
1051        /* register callback to get interface error NTF */
1052        NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
1053    }
1054    else
1055    {
1056        /* RF discovery is started but there is no valid technology or protocol to discover */
1057        nfa_dm_disc_notify_started (NFA_STATUS_OK);
1058    }
1059}
1060
1061/*******************************************************************************
1062**
1063** Function         nfa_dm_notify_discovery
1064**
1065** Description      Send RF discovery notification to upper layer
1066**
1067** Returns          void
1068**
1069*******************************************************************************/
1070static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data)
1071{
1072    tNFA_CONN_EVT_DATA conn_evt;
1073
1074    /* let application select a device */
1075    conn_evt.disc_result.status = NFA_STATUS_OK;
1076    memcpy (&(conn_evt.disc_result.discovery_ntf),
1077            &(p_data->nfc_discover.result),
1078            sizeof (tNFC_RESULT_DEVT));
1079
1080    nfa_dm_conn_cback_event_notify (NFA_DISC_RESULT_EVT, &conn_evt);
1081}
1082
1083/*******************************************************************************
1084**
1085** Function         nfa_dm_disc_notify_activation
1086**
1087** Description      Send RF activation notification to sub-module
1088**
1089** Returns          NFA_STATUS_OK if success
1090**
1091*******************************************************************************/
1092static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data)
1093{
1094    UINT8   xx, host_id_in_LRT;
1095    UINT8   iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
1096
1097    tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
1098    tNFC_PROTOCOL       protocol    = p_data->activate.protocol;
1099
1100    tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
1101
1102    NFA_TRACE_DEBUG2 ("nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
1103                       tech_n_mode, protocol);
1104
1105    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1106    {
1107        nfa_dm_cb.disc_cb.activated_tech_mode    = tech_n_mode;
1108        nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
1109        nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1110        nfa_dm_cb.disc_cb.activated_protocol     = protocol;
1111        nfa_dm_cb.disc_cb.activated_handle       = NFA_HANDLE_INVALID;
1112
1113        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1114            (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1115
1116        return (NFA_STATUS_OK);
1117    }
1118
1119    /* if this is NFCEE direct RF interface, notify activation to whoever listening UICC */
1120    if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
1121    {
1122        for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1123        {
1124            if (  (nfa_dm_cb.disc_cb.entry[xx].in_use)
1125                &&(nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH))
1126            {
1127                nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
1128                nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1129                nfa_dm_cb.disc_cb.activated_protocol     = NFC_PROTOCOL_UNKNOWN;
1130                nfa_dm_cb.disc_cb.activated_handle       = xx;
1131
1132                NFA_TRACE_DEBUG2 ("activated_rf_interface:0x%x, activated_handle: 0x%x",
1133                                   nfa_dm_cb.disc_cb.activated_rf_interface,
1134                                   nfa_dm_cb.disc_cb.activated_handle);
1135
1136                if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1137                    (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1138
1139                return (NFA_STATUS_OK);
1140            }
1141        }
1142        return (NFA_STATUS_FAILED);
1143    }
1144
1145    /* get bit mask of technolgies/mode and protocol */
1146    activated_disc_mask = nfa_dm_disc_get_disc_mask (tech_n_mode, protocol);
1147
1148    /* get host ID of technology from listen mode routing table */
1149    if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1150    {
1151        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
1152    }
1153    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1154    {
1155        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
1156    }
1157    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1158    {
1159        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
1160    }
1161    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
1162    {
1163        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
1164    }
1165    else    /* DH only */
1166    {
1167        host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1168    }
1169
1170    if (protocol == NFC_PROTOCOL_NFC_DEP)
1171    {
1172        /* Force NFC-DEP to the host */
1173        host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1174    }
1175
1176    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1177    {
1178        /* if any matching NFC technology and protocol */
1179        if (nfa_dm_cb.disc_cb.entry[xx].in_use)
1180        {
1181            if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT)
1182            {
1183                if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & activated_disc_mask)
1184                    break;
1185            }
1186            else
1187            {
1188                /* check ISO-DEP listening even if host in LRT is not matched */
1189                if (protocol == NFC_PROTOCOL_ISO_DEP)
1190                {
1191                    if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1192                        &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP))
1193                    {
1194                        iso_dep_t3t__listen = xx;
1195                    }
1196                    else if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1197                             &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP))
1198                    {
1199                        iso_dep_t3t__listen = xx;
1200                    }
1201                }
1202                /* check T3T listening even if host in LRT is not matched */
1203                else if (protocol == NFC_PROTOCOL_T3T)
1204                {
1205                    if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1206                        &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LF_T3T))
1207                    {
1208                        iso_dep_t3t__listen = xx;
1209                    }
1210                }
1211            }
1212        }
1213    }
1214
1215    if (xx >= NFA_DM_DISC_NUM_ENTRIES)
1216    {
1217        /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
1218        xx = iso_dep_t3t__listen;
1219    }
1220
1221    if (xx < NFA_DM_DISC_NUM_ENTRIES)
1222    {
1223        nfa_dm_cb.disc_cb.activated_tech_mode    = tech_n_mode;
1224        nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
1225        nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1226        nfa_dm_cb.disc_cb.activated_protocol     = protocol;
1227        nfa_dm_cb.disc_cb.activated_handle       = xx;
1228
1229        NFA_TRACE_DEBUG2 ("activated_protocol:0x%x, activated_handle: 0x%x",
1230                           nfa_dm_cb.disc_cb.activated_protocol,
1231                           nfa_dm_cb.disc_cb.activated_handle);
1232
1233        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1234            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1235
1236        return (NFA_STATUS_OK);
1237    }
1238    else
1239    {
1240        nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1241        nfa_dm_cb.disc_cb.activated_handle   = NFA_HANDLE_INVALID;
1242        return (NFA_STATUS_FAILED);
1243    }
1244}
1245
1246/*******************************************************************************
1247**
1248** Function         nfa_dm_disc_notify_deactivation
1249**
1250** Description      Send deactivation notification to sub-module
1251**
1252** Returns          None
1253**
1254*******************************************************************************/
1255static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event,
1256                                             tNFC_DISCOVER *p_data)
1257{
1258    tNFA_HANDLE         xx;
1259    tNFA_DM_RF_DISC_EVT disc_evt;
1260
1261    NFA_TRACE_DEBUG1 ("nfa_dm_disc_notify_deactivation (): activated_handle=%d",
1262                       nfa_dm_cb.disc_cb.activated_handle);
1263
1264    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
1265    {
1266        NFA_TRACE_DEBUG0 ("nfa_dm_disc_notify_deactivation (): for presence check");
1267        return;
1268    }
1269
1270    if (sm_event == NFA_DM_RF_DEACTIVATE_RSP)
1271    {
1272        /*
1273        ** Activation has been aborted by upper layer in NFA_DM_RFST_W4_HOST_SELECT
1274        ** or NFA_DM_RFST_LISTEN_SLEEP
1275        */
1276        disc_evt = NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT;
1277    }
1278    else
1279    {
1280        /* Received deactivation NTF */
1281        disc_evt = NFA_DM_RF_DISC_DEACTIVATED_EVT;
1282    }
1283
1284    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1285    {
1286        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1287            (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (disc_evt, p_data);
1288    }
1289    else
1290    {
1291        /* notify event to activated module */
1292        xx = nfa_dm_cb.disc_cb.activated_handle;
1293
1294        if (  (sm_event == NFA_DM_RF_DEACTIVATE_RSP)
1295            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)  )
1296        {
1297            /* Don't remove handle in NFA_DM_RFST_W4_HOST_SELECT or NFA_DM_RFST_LISTEN_SLEEP */
1298            nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1299        }
1300
1301        if ((xx < NFA_DM_DISC_NUM_ENTRIES) && (nfa_dm_cb.disc_cb.entry[xx].in_use))
1302        {
1303            if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1304                (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (disc_evt, p_data);
1305        }
1306    }
1307
1308    /* clear activated information */
1309    nfa_dm_cb.disc_cb.activated_tech_mode    = 0;
1310    nfa_dm_cb.disc_cb.activated_rf_disc_id   = 0;
1311    nfa_dm_cb.disc_cb.activated_rf_interface = 0;
1312    nfa_dm_cb.disc_cb.activated_protocol     = NFA_PROTOCOL_INVALID;
1313}
1314
1315/*******************************************************************************
1316**
1317** Function         nfa_dm_disc_presence_check
1318**
1319** Description      Perform legacy presence check (put tag to sleep, then
1320**                  wake it up to see if tag is present)
1321**
1322** Returns          TRUE if operation started
1323**
1324*******************************************************************************/
1325tNFC_STATUS nfa_dm_disc_presence_check (void)
1326{
1327    tNFC_STATUS status = NFC_STATUS_FAILED;
1328
1329    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
1330    {
1331        /* Deactivate to sleep mode */
1332        status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
1333        if (status == NFC_STATUS_OK)
1334        {
1335            /* deactivate to sleep is sent on behave of presence check.
1336             * set the presence check information in control block */
1337            nfa_dm_cb.disc_cb.disc_flags          |= NFA_DM_DISC_FLAGS_CHECKING;
1338            nfa_dm_cb.presence_check_deact_pending = FALSE;
1339        }
1340    }
1341
1342    return (status);
1343}
1344
1345/*******************************************************************************
1346**
1347** Function         nfa_dm_disc_end_presence_check
1348**
1349** Description      Perform legacy presence check (put tag to sleep, then
1350**                  wake it up to see if tag is present)
1351**
1352** Returns          TRUE if operation started
1353**
1354*******************************************************************************/
1355static void nfa_dm_disc_end_presence_check (tNFC_STATUS status)
1356{
1357    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
1358    {
1359        /* notify RW module that presence checking is finished */
1360        nfa_rw_handle_presence_check_rsp (status);
1361        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1362        if (nfa_dm_cb.presence_check_deact_pending)
1363        {
1364            nfa_dm_cb.presence_check_deact_pending = FALSE;
1365            nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
1366                                          (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.presence_check_deact_type);
1367        }
1368    }
1369}
1370
1371/*******************************************************************************
1372**
1373** Function         nfa_dm_disc_data_cback
1374**
1375** Description      Monitoring interface error through data callback
1376**
1377** Returns          void
1378**
1379*******************************************************************************/
1380static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
1381{
1382    NFA_TRACE_DEBUG0 ("nfa_dm_disc_data_cback ()");
1383
1384    /* if selection failed */
1385    if (event == NFC_ERROR_CEVT)
1386    {
1387        nfa_dm_disc_sm_execute (NFA_DM_CORE_INTF_ERROR_NTF, NULL);
1388    }
1389    else if (event == NFC_DATA_CEVT)
1390    {
1391        GKI_freebuf (p_data->data.p_data);
1392    }
1393}
1394
1395/*******************************************************************************
1396**
1397** Function         nfa_dm_disc_new_state
1398**
1399** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1400**
1401** Returns          void
1402**
1403*******************************************************************************/
1404void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state)
1405{
1406    tNFA_CONN_EVT_DATA      evt_data;
1407    tNFA_DM_RF_DISC_STATE   old_state = nfa_dm_cb.disc_cb.disc_state;
1408
1409#if (BT_TRACE_VERBOSE == TRUE)
1410    NFA_TRACE_DEBUG5 ("nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) disc_flags: 0x%x",
1411                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
1412                       nfa_dm_disc_state_2_str (new_state), new_state, nfa_dm_cb.disc_cb.disc_flags);
1413#else
1414    NFA_TRACE_DEBUG3 ("nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
1415                       nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
1416#endif
1417    nfa_dm_cb.disc_cb.disc_state = new_state;
1418    if (new_state == NFA_DM_RFST_IDLE)
1419    {
1420        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
1421        {
1422            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
1423
1424            /* if exclusive RF control is stopping */
1425            if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
1426            {
1427                if (old_state > NFA_DM_RFST_DISCOVERY)
1428                {
1429                    /* notify deactivation to application */
1430                    evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1431                    nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
1432                }
1433
1434                nfa_dm_rel_excl_rf_control_and_notify ();
1435            }
1436            else
1437            {
1438                evt_data.status = NFA_STATUS_OK;
1439                nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
1440            }
1441        }
1442        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
1443        {
1444            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
1445            nfa_sys_check_disabled ();
1446        }
1447    }
1448}
1449
1450/*******************************************************************************
1451**
1452** Function         nfa_dm_disc_sm_idle
1453**
1454** Description      Processing discovery events in NFA_DM_RFST_IDLE state
1455**
1456** Returns          void
1457**
1458*******************************************************************************/
1459static void nfa_dm_disc_sm_idle (tNFA_DM_RF_DISC_SM_EVENT event,
1460                                 tNFA_DM_RF_DISC_DATA *p_data)
1461{
1462    UINT8              xx;
1463
1464    switch (event)
1465    {
1466    case NFA_DM_RF_DISCOVER_CMD:
1467        nfa_dm_start_rf_discover ();
1468        break;
1469
1470    case NFA_DM_RF_DISCOVER_RSP:
1471        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1472
1473        if (p_data->nfc_discover.status == NFC_STATUS_OK)
1474        {
1475            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
1476
1477            /* if RF discovery was stopped while waiting for response */
1478            if (nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_STOPPING|NFA_DM_DISC_FLAGS_DISABLING))
1479            {
1480                /* stop discovery */
1481                nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1482                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1483                break;
1484            }
1485
1486            if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1487            {
1488                if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
1489                {
1490                    nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
1491
1492                    if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1493                        (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
1494                }
1495            }
1496            else
1497            {
1498                /* notify event to each module which is waiting for start */
1499                for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1500                {
1501                    /* if registered module is waiting for starting discovery */
1502                    if (  (nfa_dm_cb.disc_cb.entry[xx].in_use)
1503                        &&(nfa_dm_cb.disc_cb.dm_disc_mask & nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask)
1504                        &&(nfa_dm_cb.disc_cb.entry[xx].disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)  )
1505                    {
1506                        nfa_dm_cb.disc_cb.entry[xx].disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
1507
1508                        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1509                            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
1510                    }
1511                }
1512
1513            }
1514            nfa_dm_disc_notify_started (p_data->nfc_discover.status);
1515        }
1516        else
1517        {
1518            /* in rare case that the discovery states of NFCC and DH mismatch and NFCC rejects Discover Cmd
1519             * deactivate idle and then start disvocery when got deactivate rsp */
1520            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1521            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1522        }
1523        break;
1524
1525    case NFA_DM_RF_DEACTIVATE_RSP:
1526        /* restart discovery */
1527        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1528        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
1529        {
1530            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
1531            nfa_sys_check_disabled ();
1532        }
1533        else
1534            nfa_dm_start_rf_discover ();
1535        break;
1536
1537    case NFA_DM_LP_LISTEN_CMD:
1538        nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
1539        break;
1540
1541    default:
1542        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_idle (): Unexpected discovery event");
1543        break;
1544    }
1545}
1546
1547/*******************************************************************************
1548**
1549** Function         nfa_dm_disc_sm_discovery
1550**
1551** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
1552**
1553** Returns          void
1554**
1555*******************************************************************************/
1556static void nfa_dm_disc_sm_discovery (tNFA_DM_RF_DISC_SM_EVENT event,
1557                                      tNFA_DM_RF_DISC_DATA *p_data)
1558{
1559    switch (event)
1560    {
1561    case NFA_DM_RF_DEACTIVATE_CMD:
1562        /* if deactivate CMD was not sent to NFCC */
1563        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
1564        {
1565            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1566            NFC_Deactivate (p_data->deactivate_type);
1567        }
1568        break;
1569    case NFA_DM_RF_DEACTIVATE_RSP:
1570        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1571        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1572        nfa_dm_start_rf_discover ();
1573        break;
1574    case NFA_DM_RF_DISCOVER_NTF:
1575        nfa_dm_disc_new_state (NFA_DM_RFST_W4_ALL_DISCOVERIES);
1576        nfa_dm_notify_discovery (p_data);
1577        break;
1578    case NFA_DM_RF_INTF_ACTIVATED_NTF:
1579        if (p_data->nfc_discover.activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
1580        {
1581            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
1582        }
1583        else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80)
1584        {
1585            /* Listen mode */
1586            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
1587        }
1588        else
1589        {
1590            /* Poll mode */
1591            nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
1592        }
1593
1594        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
1595        {
1596            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
1597
1598            /* after receiving deactivate event, restart discovery */
1599            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1600        }
1601        break;
1602
1603    case NFA_DM_LP_LISTEN_CMD:
1604        break;
1605    case NFA_DM_CORE_INTF_ERROR_NTF:
1606        break;
1607    default:
1608        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_discovery (): Unexpected discovery event");
1609        break;
1610    }
1611}
1612
1613/*******************************************************************************
1614**
1615** Function         nfa_dm_disc_sm_w4_all_discoveries
1616**
1617** Description      Processing discovery events in NFA_DM_RFST_W4_ALL_DISCOVERIES state
1618**
1619** Returns          void
1620**
1621*******************************************************************************/
1622static void nfa_dm_disc_sm_w4_all_discoveries (tNFA_DM_RF_DISC_SM_EVENT event,
1623                                               tNFA_DM_RF_DISC_DATA *p_data)
1624{
1625    switch (event)
1626    {
1627    case NFA_DM_RF_DEACTIVATE_CMD:
1628        /* if deactivate CMD was not sent to NFCC */
1629        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
1630        {
1631            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1632            /* only IDLE mode is allowed */
1633            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1634        }
1635        break;
1636    case NFA_DM_RF_DEACTIVATE_RSP:
1637        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1638        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1639        nfa_dm_start_rf_discover ();
1640        break;
1641    case NFA_DM_RF_DISCOVER_NTF:
1642        /* Notification Type = NCI_DISCOVER_NTF_LAST or NCI_DISCOVER_NTF_LAST_ABORT */
1643        if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE)
1644        {
1645            nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
1646        }
1647        nfa_dm_notify_discovery (p_data);
1648        break;
1649    case NFA_DM_RF_INTF_ACTIVATED_NTF:
1650        /*
1651        ** This is only for ISO15693.
1652        ** FW sends activation NTF when all responses are received from tags without host selecting.
1653        */
1654        nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
1655
1656        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
1657        {
1658            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
1659
1660            /* after receiving deactivate event, restart discovery */
1661            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1662        }
1663        break;
1664    default:
1665        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_all_discoveries (): Unexpected discovery event");
1666        break;
1667    }
1668}
1669
1670/*******************************************************************************
1671**
1672** Function         nfa_dm_disc_sm_w4_host_select
1673**
1674** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT state
1675**
1676** Returns          void
1677**
1678*******************************************************************************/
1679static void nfa_dm_disc_sm_w4_host_select (tNFA_DM_RF_DISC_SM_EVENT event,
1680                                           tNFA_DM_RF_DISC_DATA *p_data)
1681{
1682    tNFA_CONN_EVT_DATA conn_evt;
1683    tNFA_DM_DISC_FLAGS  old_pres_check_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
1684    BOOLEAN             pres_check_event = FALSE;
1685    BOOLEAN             pres_check_event_processed = FALSE;
1686
1687    switch (event)
1688    {
1689    case NFA_DM_RF_DISCOVER_SELECT_CMD:
1690        /* if not waiting to deactivate */
1691        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
1692        {
1693            NFC_DiscoverySelect (p_data->select.rf_disc_id,
1694                                 p_data->select.protocol,
1695                                 p_data->select.rf_interface);
1696        }
1697        else
1698        {
1699            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
1700        }
1701        break;
1702
1703    case NFA_DM_RF_DISCOVER_SELECT_RSP:
1704        pres_check_event = TRUE;
1705        /* notify application status of selection */
1706        if (p_data->nfc_discover.status == NFC_STATUS_OK)
1707        {
1708            pres_check_event_processed = TRUE;
1709            conn_evt.status = NFA_STATUS_OK;
1710            /* register callback to get interface error NTF */
1711            NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
1712        }
1713        else
1714            conn_evt.status = NFA_STATUS_FAILED;
1715
1716        if (!old_pres_check_flag)
1717        {
1718            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, p_data->nfc_discover.status);
1719        }
1720        break;
1721    case NFA_DM_RF_INTF_ACTIVATED_NTF:
1722        nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
1723        if (old_pres_check_flag)
1724        {
1725            /* notify RW module of presence of tag */
1726            nfa_rw_handle_presence_check_rsp (NFC_STATUS_OK);
1727            if (nfa_dm_cb.presence_check_deact_pending)
1728            {
1729                nfa_dm_cb.presence_check_deact_pending = FALSE;
1730                nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
1731                                       (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.presence_check_deact_type);
1732            }
1733        }
1734
1735        else if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
1736        {
1737            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
1738
1739            /* after receiving deactivate event, restart discovery */
1740            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1741        }
1742        break;
1743    case NFA_DM_RF_DEACTIVATE_CMD:
1744        if (old_pres_check_flag)
1745        {
1746            nfa_dm_cb.presence_check_deact_pending = TRUE;
1747            nfa_dm_cb.presence_check_deact_type    = p_data->deactivate_type;
1748        }
1749        /* if deactivate CMD was not sent to NFCC */
1750        else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
1751        {
1752            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1753            /* only IDLE mode is allowed */
1754            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1755        }
1756        break;
1757    case NFA_DM_RF_DEACTIVATE_RSP:
1758        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1759        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1760        nfa_dm_start_rf_discover ();
1761        /* notify exiting from host select state */
1762        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
1763        break;
1764
1765    case NFA_DM_CORE_INTF_ERROR_NTF:
1766        pres_check_event    = TRUE;
1767        if (!old_pres_check_flag)
1768        {
1769            /* target activation failed, upper layer may deactivate or select again */
1770            conn_evt.status = NFA_STATUS_FAILED;
1771            nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
1772        }
1773        break;
1774    default:
1775        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
1776        break;
1777    }
1778
1779    if (old_pres_check_flag && pres_check_event && !pres_check_event_processed)
1780    {
1781        /* performing presence check for unknow protocol and exception conditions happened
1782         * clear presence check information and report failure */
1783        nfa_dm_disc_end_presence_check (NFC_STATUS_FAILED);
1784        if (nfa_dm_cb.presence_check_deact_pending)
1785        {
1786            nfa_dm_cb.presence_check_deact_pending = FALSE;
1787
1788            NFC_Deactivate (nfa_dm_cb.presence_check_deact_type);
1789        }
1790    }
1791}
1792
1793/*******************************************************************************
1794**
1795** Function         nfa_dm_disc_sm_poll_active
1796**
1797** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
1798**
1799** Returns          void
1800**
1801*******************************************************************************/
1802static void nfa_dm_disc_sm_poll_active (tNFA_DM_RF_DISC_SM_EVENT event,
1803                                        tNFA_DM_RF_DISC_DATA *p_data)
1804{
1805    tNFC_STATUS status;
1806    tNFA_DM_DISC_FLAGS  old_pres_check_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
1807    BOOLEAN             pres_check_event = FALSE;
1808    BOOLEAN             pres_check_event_processed = FALSE;
1809
1810    switch (event)
1811    {
1812    case NFA_DM_RF_DEACTIVATE_CMD:
1813        if (old_pres_check_flag)
1814        {
1815            /* presence check is already enabled when deactivate cmd is requested,
1816             * keep the information in control block to issue it later */
1817            nfa_dm_cb.presence_check_deact_pending = TRUE;
1818            nfa_dm_cb.presence_check_deact_type    = p_data->deactivate_type;
1819        }
1820        else
1821        {
1822            status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
1823        }
1824
1825        break;
1826    case NFA_DM_RF_DEACTIVATE_RSP:
1827        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1828        /* register callback to get interface error NTF */
1829        NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
1830        break;
1831    case NFA_DM_RF_DEACTIVATE_NTF:
1832        pres_check_event    = TRUE;
1833        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1834        if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
1835            ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
1836        {
1837            nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
1838            if (old_pres_check_flag)
1839            {
1840                pres_check_event_processed  = TRUE;
1841                /* process pending deactivate request */
1842                if (nfa_dm_cb.presence_check_deact_pending)
1843                {
1844                    nfa_dm_cb.presence_check_deact_pending = FALSE;
1845                    /* notify RW module that presence checking is finished */
1846                    nfa_dm_disc_end_presence_check (NFC_STATUS_OK);
1847
1848                    if (nfa_dm_cb.presence_check_deact_type == NFC_DEACTIVATE_TYPE_IDLE)
1849                        NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1850                    else
1851                        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
1852                }
1853                else
1854                {
1855                    /* Successfully went to sleep mode for presence check */
1856                    /* Now wake up the tag to see if it is present */
1857                    NFC_DiscoverySelect (nfa_dm_cb.disc_cb.activated_rf_disc_id,
1858                                         nfa_dm_cb.disc_cb.activated_protocol,
1859                                         nfa_dm_cb.disc_cb.activated_rf_interface);
1860                }
1861
1862            }
1863        }
1864        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
1865        {
1866            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1867            nfa_dm_start_rf_discover ();
1868        }
1869        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
1870        {
1871            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
1872            if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
1873            {
1874                /* stop discovery */
1875                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1876            }
1877        }
1878        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
1879        break;
1880
1881    case NFA_DM_CORE_INTF_ERROR_NTF:
1882        pres_check_event    = TRUE;
1883        NFC_Deactivate (NFC_DEACTIVATE_TYPE_DISCOVERY);
1884        break;
1885
1886    default:
1887        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
1888        break;
1889    }
1890
1891    if (old_pres_check_flag && pres_check_event && !pres_check_event_processed)
1892    {
1893        /* performing presence check for unknow protocol and exception conditions happened
1894         * clear presence check information and report failure */
1895        nfa_dm_disc_end_presence_check (NFC_STATUS_FAILED);
1896        if (nfa_dm_cb.presence_check_deact_pending)
1897        {
1898            nfa_dm_cb.presence_check_deact_pending = FALSE;
1899
1900            NFC_Deactivate (nfa_dm_cb.presence_check_deact_type);
1901        }
1902    }
1903}
1904
1905/*******************************************************************************
1906**
1907** Function         nfa_dm_disc_sm_listen_active
1908**
1909** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE state
1910**
1911** Returns          void
1912**
1913*******************************************************************************/
1914static void nfa_dm_disc_sm_listen_active (tNFA_DM_RF_DISC_SM_EVENT event,
1915                                          tNFA_DM_RF_DISC_DATA     *p_data)
1916{
1917    switch (event)
1918    {
1919    case NFA_DM_RF_DEACTIVATE_CMD:
1920        nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
1921        break;
1922    case NFA_DM_RF_DEACTIVATE_RSP:
1923        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1924        break;
1925    case NFA_DM_RF_DEACTIVATE_NTF:
1926        /* clear both W4_RSP and W4_NTF because of race condition between deactivat CMD and link loss */
1927        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
1928
1929        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
1930        {
1931            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1932            nfa_dm_start_rf_discover ();
1933        }
1934        else if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
1935                 ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
1936        {
1937            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_SLEEP);
1938        }
1939        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
1940        {
1941            /* Discovery */
1942            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
1943            if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
1944            {
1945                /* stop discovery */
1946                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1947            }
1948        }
1949        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
1950        break;
1951
1952    case NFA_DM_CORE_INTF_ERROR_NTF:
1953        break;
1954    default:
1955        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
1956        break;
1957    }
1958}
1959
1960/*******************************************************************************
1961**
1962** Function         nfa_dm_disc_sm_listen_sleep
1963**
1964** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP state
1965**
1966** Returns          void
1967**
1968*******************************************************************************/
1969static void nfa_dm_disc_sm_listen_sleep (tNFA_DM_RF_DISC_SM_EVENT event,
1970                                         tNFA_DM_RF_DISC_DATA *p_data)
1971{
1972    switch (event)
1973    {
1974    case NFA_DM_RF_DEACTIVATE_CMD:
1975        nfa_dm_send_deactivate_cmd (p_data->deactivate_type);
1976        break;
1977    case NFA_DM_RF_DEACTIVATE_RSP:
1978        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1979        /* if deactivate type in CMD was IDLE */
1980        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
1981        {
1982            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1983            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
1984        }
1985        break;
1986    case NFA_DM_RF_DEACTIVATE_NTF:
1987        /* clear both W4_RSP and W4_NTF because of race condition between deactivat CMD and link loss */
1988        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
1989        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
1990        {
1991            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1992            nfa_dm_start_rf_discover ();
1993        }
1994        else if (p_data->nfc_discover.deactivate.type == NFA_DEACTIVATE_TYPE_DISCOVERY)
1995        {
1996            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
1997        }
1998        else
1999        {
2000            NFA_TRACE_ERROR0 ("Unexpected deactivation type");
2001            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2002            nfa_dm_start_rf_discover ();
2003        }
2004        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2005        break;
2006    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2007        nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
2008        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
2009        {
2010            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
2011
2012            /* after receiving deactivate event, restart discovery */
2013            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2014        }
2015        break;
2016    default:
2017        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_sleep (): Unexpected discovery event");
2018        break;
2019    }
2020}
2021
2022/*******************************************************************************
2023**
2024** Function         nfa_dm_disc_sm_lp_listen
2025**
2026** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
2027**
2028** Returns          void
2029**
2030*******************************************************************************/
2031static void nfa_dm_disc_sm_lp_listen (tNFA_DM_RF_DISC_SM_EVENT event,
2032                                           tNFA_DM_RF_DISC_DATA *p_data)
2033{
2034    switch (event)
2035    {
2036    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2037        nfa_dm_disc_new_state (NFA_DM_RFST_LP_ACTIVE);
2038        nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
2039        break;
2040
2041    default:
2042        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_listen (): Unexpected discovery event");
2043        break;
2044    }
2045}
2046
2047/*******************************************************************************
2048**
2049** Function         nfa_dm_disc_sm_lp_active
2050**
2051** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
2052**
2053** Returns          void
2054**
2055*******************************************************************************/
2056static void nfa_dm_disc_sm_lp_active (tNFA_DM_RF_DISC_SM_EVENT event,
2057                                           tNFA_DM_RF_DISC_DATA *p_data)
2058{
2059    switch (event)
2060    {
2061    case NFA_DM_RF_DEACTIVATE_NTF:
2062        nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
2063        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2064        break;
2065    default:
2066        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_active (): Unexpected discovery event");
2067        break;
2068    }
2069}
2070
2071/*******************************************************************************
2072**
2073** Function         nfa_dm_disc_sm_execute
2074**
2075** Description      Processing discovery related events
2076**
2077** Returns          void
2078**
2079*******************************************************************************/
2080void nfa_dm_disc_sm_execute (tNFA_DM_RF_DISC_SM_EVENT event, tNFA_DM_RF_DISC_DATA *p_data)
2081{
2082#if (BT_TRACE_VERBOSE == TRUE)
2083    NFA_TRACE_DEBUG5 ("nfa_dm_disc_sm_execute (): state: %s (%d), event: %s(%d) disc_flags: 0x%x",
2084                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
2085                       nfa_dm_disc_event_2_str (event), event, nfa_dm_cb.disc_cb.disc_flags);
2086#else
2087    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute(): state: %d, event:%d disc_flags: 0x%x",
2088                       nfa_dm_cb.disc_cb.disc_state, event, nfa_dm_cb.disc_cb.disc_flags);
2089#endif
2090
2091    switch (nfa_dm_cb.disc_cb.disc_state)
2092    {
2093    /*  RF Discovery State - Idle */
2094    case NFA_DM_RFST_IDLE:
2095        nfa_dm_disc_sm_idle (event, p_data);
2096        break;
2097
2098    /* RF Discovery State - Discovery */
2099    case NFA_DM_RFST_DISCOVERY:
2100        nfa_dm_disc_sm_discovery (event, p_data);
2101        break;
2102
2103    /*RF Discovery State - Wait for all discoveries */
2104    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2105        nfa_dm_disc_sm_w4_all_discoveries (event, p_data);
2106        break;
2107
2108    /* RF Discovery State - Wait for host selection */
2109    case NFA_DM_RFST_W4_HOST_SELECT:
2110        nfa_dm_disc_sm_w4_host_select (event, p_data);
2111        break;
2112
2113    /* RF Discovery State - Poll mode activated */
2114    case NFA_DM_RFST_POLL_ACTIVE:
2115        nfa_dm_disc_sm_poll_active (event, p_data);
2116        break;
2117
2118    /* RF Discovery State - listen mode activated */
2119    case NFA_DM_RFST_LISTEN_ACTIVE:
2120        nfa_dm_disc_sm_listen_active (event, p_data);
2121        break;
2122
2123    /* RF Discovery State - listen mode sleep */
2124    case NFA_DM_RFST_LISTEN_SLEEP:
2125        nfa_dm_disc_sm_listen_sleep (event, p_data);
2126        break;
2127
2128    /* Listening in Low Power mode    */
2129    case NFA_DM_RFST_LP_LISTEN:
2130        nfa_dm_disc_sm_lp_listen (event, p_data);
2131        break;
2132
2133    /* Activated in Low Power mode    */
2134    case NFA_DM_RFST_LP_ACTIVE:
2135        nfa_dm_disc_sm_lp_active (event, p_data);
2136        break;
2137    }
2138#if (BT_TRACE_VERBOSE == TRUE)
2139    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute (): new state: %s (%d), disc_flags: 0x%x",
2140                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
2141                       nfa_dm_cb.disc_cb.disc_flags);
2142#else
2143    NFA_TRACE_DEBUG2 ("nfa_dm_disc_sm_execute(): new state: %d,  disc_flags: 0x%x",
2144                       nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
2145#endif
2146}
2147
2148/*******************************************************************************
2149**
2150** Function         nfa_dm_add_rf_discover
2151**
2152** Description      Add discovery configuration and callback function
2153**
2154** Returns          valid handle if success
2155**
2156*******************************************************************************/
2157tNFA_HANDLE nfa_dm_add_rf_discover (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
2158                                    tNFA_DM_DISC_HOST_ID         host_id,
2159                                    tNFA_DISCOVER_CBACK         *p_disc_cback)
2160{
2161    UINT8       xx;
2162
2163    NFA_TRACE_DEBUG1 ("nfa_dm_add_rf_discover () disc_mask=0x%x", disc_mask);
2164
2165    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
2166    {
2167        if (!nfa_dm_cb.disc_cb.entry[xx].in_use)
2168        {
2169            nfa_dm_cb.disc_cb.entry[xx].in_use              = TRUE;
2170            nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
2171            nfa_dm_cb.disc_cb.entry[xx].host_id             = host_id;
2172            nfa_dm_cb.disc_cb.entry[xx].p_disc_cback        = p_disc_cback;
2173            nfa_dm_cb.disc_cb.entry[xx].disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
2174            return xx;
2175        }
2176    }
2177
2178    return NFA_HANDLE_INVALID;
2179}
2180
2181/*******************************************************************************
2182**
2183** Function         nfa_dm_start_excl_discovery
2184**
2185** Description      Start exclusive RF discovery
2186**
2187** Returns          void
2188**
2189*******************************************************************************/
2190void nfa_dm_start_excl_discovery (tNFA_TECHNOLOGY_MASK poll_tech_mask,
2191                                  tNFA_LISTEN_CFG *p_listen_cfg,
2192                                  tNFA_DISCOVER_CBACK  *p_disc_cback)
2193{
2194    tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
2195
2196    NFA_TRACE_DEBUG0 ("nfa_dm_start_excl_discovery ()");
2197
2198    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A)
2199    {
2200        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
2201        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
2202        poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
2203        poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
2204        poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
2205    }
2206    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
2207    {
2208        poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
2209    }
2210    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B)
2211    {
2212        poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
2213    }
2214    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
2215    {
2216        poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
2217        poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
2218    }
2219    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
2220    {
2221        poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
2222    }
2223    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
2224    {
2225        poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
2226    }
2227    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
2228    {
2229        poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
2230    }
2231    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
2232    {
2233        poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
2234    }
2235
2236    nfa_dm_cb.disc_cb.excl_disc_entry.in_use              = TRUE;
2237    nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
2238    nfa_dm_cb.disc_cb.excl_disc_entry.host_id             = NFA_DM_DISC_HOST_ID_DH;
2239    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback        = p_disc_cback;
2240    nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
2241
2242    memcpy (&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg, sizeof (tNFA_LISTEN_CFG));
2243
2244    nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_CMD, NULL);
2245}
2246
2247/*******************************************************************************
2248**
2249** Function         nfa_dm_stop_excl_discovery
2250**
2251** Description      Stop exclusive RF discovery
2252**
2253** Returns          void
2254**
2255*******************************************************************************/
2256void nfa_dm_stop_excl_discovery (void)
2257{
2258    NFA_TRACE_DEBUG0 ("nfa_dm_stop_excl_discovery ()");
2259
2260    nfa_dm_cb.disc_cb.excl_disc_entry.in_use       = FALSE;
2261    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
2262}
2263
2264/*******************************************************************************
2265**
2266** Function         nfa_dm_delete_rf_discover
2267**
2268** Description      Remove discovery configuration and callback function
2269**
2270** Returns          void
2271**
2272*******************************************************************************/
2273void nfa_dm_delete_rf_discover (tNFA_HANDLE handle)
2274{
2275    NFA_TRACE_DEBUG1 ("nfa_dm_delete_rf_discover () handle=0x%x", handle);
2276
2277    if (handle < NFA_DM_DISC_NUM_ENTRIES)
2278    {
2279        nfa_dm_cb.disc_cb.entry[handle].in_use = FALSE;
2280    }
2281    else
2282    {
2283        NFA_TRACE_ERROR0 ("Invalid discovery handle");
2284    }
2285}
2286
2287/*******************************************************************************
2288**
2289** Function         nfa_dm_rf_discover_select
2290**
2291** Description      Select target, protocol and RF interface
2292**
2293** Returns          void
2294**
2295*******************************************************************************/
2296void nfa_dm_rf_discover_select (UINT8             rf_disc_id,
2297                                       tNFA_NFC_PROTOCOL protocol,
2298                                       tNFA_INTF_TYPE    rf_interface)
2299{
2300    tNFA_DM_DISC_SELECT_PARAMS select_params;
2301    tNFA_CONN_EVT_DATA conn_evt;
2302
2303    NFA_TRACE_DEBUG3 ("nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
2304                       rf_disc_id, protocol, rf_interface);
2305
2306    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
2307    {
2308        /* state is OK: notify the status when the response is received from NFCC */
2309        select_params.rf_disc_id   = rf_disc_id;
2310        select_params.protocol     = protocol;
2311        select_params.rf_interface = rf_interface;
2312
2313        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
2314        nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_SELECT_CMD, (tNFA_DM_RF_DISC_DATA *) &select_params);
2315    }
2316    else
2317    {
2318        /* Wrong state: notify failed status right away */
2319        conn_evt.status = NFA_STATUS_FAILED;
2320        nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
2321    }
2322}
2323
2324/*******************************************************************************
2325**
2326** Function         nfa_dm_rf_deactivate
2327**
2328** Description      Deactivate NFC link
2329**
2330** Returns          NFA_STATUS_OK if success
2331**
2332*******************************************************************************/
2333tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type)
2334{
2335    NFA_TRACE_DEBUG1 ("nfa_dm_rf_deactivate () deactivate_type:0x%X", deactivate_type);
2336
2337    if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP)
2338    {
2339        if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
2340            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
2341        else
2342            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
2343    }
2344
2345    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
2346    {
2347        return NFA_STATUS_FAILED;
2348    }
2349    else
2350    {
2351        nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
2352        return NFA_STATUS_OK;
2353    }
2354}
2355
2356#if (BT_TRACE_VERBOSE == TRUE)
2357/*******************************************************************************
2358**
2359** Function         nfa_dm_disc_state_2_str
2360**
2361** Description      convert nfc discovery state to string
2362**
2363*******************************************************************************/
2364static char *nfa_dm_disc_state_2_str (UINT8 state)
2365{
2366    switch (state)
2367    {
2368    case NFA_DM_RFST_IDLE:
2369        return "IDLE";
2370
2371    case NFA_DM_RFST_DISCOVERY:
2372        return "DISCOVERY";
2373
2374    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
2375        return "W4_ALL_DISCOVERIES";
2376
2377    case NFA_DM_RFST_W4_HOST_SELECT:
2378        return "W4_HOST_SELECT";
2379
2380    case NFA_DM_RFST_POLL_ACTIVE:
2381        return "POLL_ACTIVE";
2382
2383    case NFA_DM_RFST_LISTEN_ACTIVE:
2384        return "LISTEN_ACTIVE";
2385
2386    case NFA_DM_RFST_LISTEN_SLEEP:
2387        return "LISTEN_SLEEP";
2388
2389    case NFA_DM_RFST_LP_LISTEN:
2390        return "LP_LISTEN";
2391
2392    case NFA_DM_RFST_LP_ACTIVE:
2393        return "LP_ACTIVE";
2394    }
2395    return "Unknown";
2396}
2397
2398/*******************************************************************************
2399**
2400** Function         nfa_dm_disc_event_2_str
2401**
2402** Description      convert nfc discovery RSP/NTF to string
2403**
2404*******************************************************************************/
2405static char *nfa_dm_disc_event_2_str (UINT8 event)
2406{
2407    switch (event)
2408    {
2409    case NFA_DM_RF_DISCOVER_CMD:
2410        return "DISCOVER_CMD";
2411
2412    case NFA_DM_RF_DISCOVER_RSP:
2413        return "DISCOVER_RSP";
2414
2415    case NFA_DM_RF_DISCOVER_NTF:
2416        return "DISCOVER_NTF";
2417
2418    case NFA_DM_RF_DISCOVER_SELECT_CMD:
2419        return "SELECT_CMD";
2420
2421    case NFA_DM_RF_DISCOVER_SELECT_RSP:
2422        return "SELECT_RSP";
2423
2424    case NFA_DM_RF_INTF_ACTIVATED_NTF:
2425        return "ACTIVATED_NTF";
2426
2427    case NFA_DM_RF_DEACTIVATE_CMD:
2428        return "DEACTIVATE_CMD";
2429
2430    case NFA_DM_RF_DEACTIVATE_RSP:
2431        return "DEACTIVATE_RSP";
2432
2433    case NFA_DM_RF_DEACTIVATE_NTF:
2434        return "DEACTIVATE_NTF";
2435
2436    case NFA_DM_LP_LISTEN_CMD:
2437        return "NFA_DM_LP_LISTEN_CMD";
2438
2439    case NFA_DM_CORE_INTF_ERROR_NTF:
2440        return "INTF_ERROR_NTF";
2441
2442    }
2443    return "Unknown";
2444}
2445#endif /* BT_TRACE_VERBOSE */
2446