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