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