blob: 6066381d962e4728f7f939f32c618515a7076f84 [file] [log] [blame]
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001/******************************************************************************
2 *
Evan Chue9629ba2014-01-31 11:18:47 -05003 * Copyright (C) 2010-2014 Broadcom Corporation
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08004 *
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
Martijn Coenen5c65c3a2013-03-27 13:23:36 -070019
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080020/******************************************************************************
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"
Jizhou Liao2ef08962015-06-08 16:11:04 -070032#include "nci_hmsgs.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080033#if (NFC_NFCEE_INCLUDED == TRUE)
34#include "nfa_ee_api.h"
35#include "nfa_ee_int.h"
36#endif
37#include "nfa_rw_int.h"
38
Jizhou Liao2ef08962015-06-08 16:11:04 -070039#include "nfc_int.h"
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080040/*
41** static functions
42*/
43
44static UINT8 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
45 tNFC_DISCOVER_PARAMS disc_params[],
46 UINT8 max_params);
47static tNFA_STATUS nfa_dm_set_rf_listen_mode_config (tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
48static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask);
49static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
50 tNFC_PROTOCOL protocol);
51static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data);
52static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data);
53static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event, tNFC_DISCOVER *p_data);
54static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
Evan Chu7c69b272013-05-14 12:48:36 -040055static void nfa_dm_disc_kovio_timeout_cback (TIMER_LIST_ENT *p_tle);
56static void nfa_dm_disc_report_kovio_presence_check (tNFC_STATUS status);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080057
58#if (BT_TRACE_VERBOSE == TRUE)
59static char *nfa_dm_disc_state_2_str (UINT8 state);
60static char *nfa_dm_disc_event_2_str (UINT8 event);
61#endif
62
Jizhou Liao2ef08962015-06-08 16:11:04 -070063typedef struct nfa_dm_p2p_prio_logic
64{
65 BOOLEAN isodep_detected; /* flag to check if ISO-DEP is detected */
66 BOOLEAN timer_expired; /* flag to check whether timer is expired */
67 TIMER_LIST_ENT timer_list; /*timer structure pointer */
68 UINT8 first_tech_mode;
69}nfa_dm_p2p_prio_logic_t;
70
71static nfa_dm_p2p_prio_logic_t p2p_prio_logic_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080072
73/*******************************************************************************
74**
75** Function nfa_dm_get_rf_discover_config
76**
77** Description Build RF discovery configurations from tNFA_DM_DISC_TECH_PROTO_MASK
78**
79** Returns number of RF discovery configurations
80**
81*******************************************************************************/
82static UINT8 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
83 tNFC_DISCOVER_PARAMS disc_params[],
84 UINT8 max_params)
85{
86 UINT8 num_params = 0;
87
Evan Chu67aef6c2013-08-29 13:02:54 -070088 if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED)
89 {
90 NFA_TRACE_DEBUG1 ("nfa_dm_get_rf_discover_config () listen disabled, rm listen from 0x%x", dm_disc_mask);
91 dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
92 }
Evan Chua24be4f2013-11-13 15:30:16 -050093 if (nfa_dm_is_p2p_paused ())
94 {
95 dm_disc_mask &= ~NFA_DM_DISC_MASK_NFC_DEP;
96 }
Evan Chu67aef6c2013-08-29 13:02:54 -070097
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -080098 /* Check polling A */
99 if (dm_disc_mask & ( NFA_DM_DISC_MASK_PA_T1T
100 |NFA_DM_DISC_MASK_PA_T2T
101 |NFA_DM_DISC_MASK_PA_ISO_DEP
102 |NFA_DM_DISC_MASK_PA_NFC_DEP
103 |NFA_DM_DISC_MASK_P_LEGACY) )
104 {
105 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A;
Evan Chu91ada912013-06-21 17:58:57 -0400106 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pa;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800107 num_params++;
108
109 if (num_params >= max_params)
110 return num_params;
111 }
112
113 /* Check polling B */
114 if (dm_disc_mask & NFA_DM_DISC_MASK_PB_ISO_DEP)
115 {
116 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B;
Evan Chu91ada912013-06-21 17:58:57 -0400117 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pb;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800118 num_params++;
119
120 if (num_params >= max_params)
121 return num_params;
122 }
123
124 /* Check polling F */
125 if (dm_disc_mask & ( NFA_DM_DISC_MASK_PF_T3T
126 |NFA_DM_DISC_MASK_PF_NFC_DEP) )
127 {
128 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F;
Evan Chu91ada912013-06-21 17:58:57 -0400129 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pf;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800130 num_params++;
131
132 if (num_params >= max_params)
133 return num_params;
134 }
135
136 /* Check polling A Active mode */
137 if (dm_disc_mask & NFA_DM_DISC_MASK_PAA_NFC_DEP)
138 {
139 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A_ACTIVE;
Evan Chu91ada912013-06-21 17:58:57 -0400140 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->paa;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800141 num_params++;
142
143 if (num_params >= max_params)
144 return num_params;
145 }
146
147 /* Check polling F Active mode */
148 if (dm_disc_mask & NFA_DM_DISC_MASK_PFA_NFC_DEP)
149 {
150 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F_ACTIVE;
Evan Chu91ada912013-06-21 17:58:57 -0400151 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pfa;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800152 num_params++;
153
154 if (num_params >= max_params)
155 return num_params;
156 }
157
158 /* Check listening A */
159 if (dm_disc_mask & ( NFA_DM_DISC_MASK_LA_T1T
160 |NFA_DM_DISC_MASK_LA_T2T
161 |NFA_DM_DISC_MASK_LA_ISO_DEP
162 |NFA_DM_DISC_MASK_LA_NFC_DEP) )
163 {
164 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A;
165 disc_params[num_params].frequency = 1;
166 num_params++;
167
168 if (num_params >= max_params)
169 return num_params;
170 }
171
172 /* Check listening B */
173 if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
174 {
175 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B;
176 disc_params[num_params].frequency = 1;
177 num_params++;
178
179 if (num_params >= max_params)
180 return num_params;
181 }
182
183 /* Check listening F */
184 if (dm_disc_mask & ( NFA_DM_DISC_MASK_LF_T3T
185 |NFA_DM_DISC_MASK_LF_NFC_DEP) )
186 {
187 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F;
188 disc_params[num_params].frequency = 1;
189 num_params++;
190
191 if (num_params >= max_params)
192 return num_params;
193 }
194
195 /* Check listening A Active mode */
196 if (dm_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP)
197 {
198 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE;
199 disc_params[num_params].frequency = 1;
200 num_params++;
201
202 if (num_params >= max_params)
203 return num_params;
204 }
205
206 /* Check listening F Active mode */
207 if (dm_disc_mask & NFA_DM_DISC_MASK_LFA_NFC_DEP)
208 {
209 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE;
210 disc_params[num_params].frequency = 1;
211 num_params++;
212
213 if (num_params >= max_params)
214 return num_params;
215 }
216
217 /* Check polling ISO 15693 */
218 if (dm_disc_mask & NFA_DM_DISC_MASK_P_ISO15693)
219 {
220 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_ISO15693;
Evan Chu91ada912013-06-21 17:58:57 -0400221 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pi93;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800222 num_params++;
223
224 if (num_params >= max_params)
225 return num_params;
226 }
227
228 /* Check polling B' */
229 if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME)
230 {
231 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
Evan Chu91ada912013-06-21 17:58:57 -0400232 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pbp;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800233 num_params++;
234
235 if (num_params >= max_params)
236 return num_params;
237 }
238
239 /* Check polling KOVIO */
240 if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO)
241 {
242 disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_KOVIO;
Evan Chu91ada912013-06-21 17:58:57 -0400243 disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pk;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800244 num_params++;
245
246 if (num_params >= max_params)
247 return num_params;
248 }
249
250 /* Check listening ISO 15693 */
251 if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693)
252 {
253 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
254 disc_params[num_params].frequency = 1;
255 num_params++;
256
257 if (num_params >= max_params)
258 return num_params;
259 }
260
261 /* Check listening B' */
262 if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME)
263 {
264 disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
265 disc_params[num_params].frequency = 1;
266 num_params++;
267
268 if (num_params >= max_params)
269 return num_params;
270 }
271
272 return num_params;
273}
274
275/*******************************************************************************
276**
277** Function nfa_dm_set_rf_listen_mode_config
278**
279** Description Update listening protocol to NFCC
280**
281** Returns NFA_STATUS_OK if success
282**
283*******************************************************************************/
284static tNFA_STATUS nfa_dm_set_rf_listen_mode_config (tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask)
285{
286 UINT8 params[40], *p;
287 UINT8 platform = 0;
288 UINT8 sens_info = 0;
289
290 NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_config () tech_proto_mask = 0x%08X",
291 tech_proto_mask);
292
293 /*
294 ** T1T listen LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
295 ** T2T listen LA_PROT 0x00
296 ** T3T listen No bit for T3T in LF_PROT (CE T3T set listen parameters, system code, NFCID2, etc.)
297 ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
298 ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
299 */
300
301 if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T)
302 {
303 platform = NCI_PARAM_PLATFORM_T1T;
304 }
305 else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T)
306 {
307 /* platform = 0 and sens_info = 0 */
308 }
309 else
310 {
311 if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)
312 {
313 sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
314 }
315
316 if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP)
317 {
318 sens_info |= NCI_PARAM_SEL_INFO_NFCDEP;
319 }
320 }
321
322 p = params;
323
324 /*
325 ** for Listen A
326 **
327 ** Set ATQA 0x0C00 for T1T listen
328 ** If the ATQA values are 0x0000, then the FW will use 0x0400
329 ** which works for ISODEP, T2T and NFCDEP.
330 */
Evan Chu67aef6c2013-08-29 13:02:54 -0700331 if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] == NFA_DM_DISC_HOST_ID_DH)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800332 {
333 UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
334 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
335 UINT8_TO_STREAM (p, 0x04);
336 UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
337 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
338 UINT8_TO_STREAM (p, platform);
339 UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
340 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_SEL_INFO);
341 UINT8_TO_STREAM (p, sens_info);
342 }
343 else /* Let NFCC use UICC configuration by configuring with length = 0 */
344 {
345 UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
346 UINT8_TO_STREAM (p, 0);
347 UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
348 UINT8_TO_STREAM (p, 0);
349 UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
350 UINT8_TO_STREAM (p, 0);
351 UINT8_TO_STREAM (p, NFC_PMID_LA_NFCID1);
352 UINT8_TO_STREAM (p, 0);
353 UINT8_TO_STREAM (p, NFC_PMID_LA_HIST_BY);
354 UINT8_TO_STREAM (p, 0);
355 }
356
357 /* for Listen B */
358 if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] == NFA_DM_DISC_HOST_ID_DH)
359 {
360 UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
361 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_SENSB_INFO);
362 if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
363 {
364 UINT8_TO_STREAM (p, NCI_LISTEN_PROTOCOL_ISO_DEP);
365 }
366 else
367 {
368 UINT8_TO_STREAM (p, 0x00);
369 }
370 }
371 else /* Let NFCC use UICC configuration by configuring with length = 0 */
372 {
373 UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
374 UINT8_TO_STREAM (p, 0);
375 UINT8_TO_STREAM (p, NFC_PMID_LB_NFCID0);
376 UINT8_TO_STREAM (p, 0);
377 UINT8_TO_STREAM (p, NFC_PMID_LB_APPDATA);
378 UINT8_TO_STREAM (p, 0);
379 UINT8_TO_STREAM (p, NFC_PMID_LB_ADC_FO);
380 UINT8_TO_STREAM (p, 0);
381 UINT8_TO_STREAM (p, NFC_PMID_LB_H_INFO);
382 UINT8_TO_STREAM (p, 0);
383 }
384
385 /* for Listen F */
Evan Chu7c69b272013-05-14 12:48:36 -0400386 /* NFCC can support NFC-DEP and T3T listening based on NFCID routing regardless of NFC-F tech routing */
387 UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
388 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_PROTOCOL);
Evan Chua24be4f2013-11-13 15:30:16 -0500389 if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) &&
390 !nfa_dm_is_p2p_paused() )
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800391 {
Evan Chu7c69b272013-05-14 12:48:36 -0400392 UINT8_TO_STREAM (p, NCI_LISTEN_PROTOCOL_NFC_DEP);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800393 }
394 else
395 {
Evan Chu7c69b272013-05-14 12:48:36 -0400396 UINT8_TO_STREAM (p, 0x00);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800397 }
398
399 if (p > params)
400 {
401 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
402 }
403
404 return NFA_STATUS_OK;
405}
406
407/*******************************************************************************
408**
409** Function nfa_dm_set_total_duration
410**
411** Description Update total duration to NFCC
412**
413** Returns void
414**
415*******************************************************************************/
416static void nfa_dm_set_total_duration (void)
417{
418 UINT8 params[10], *p;
419
420 NFA_TRACE_DEBUG0 ("nfa_dm_set_total_duration ()");
421
422 p = params;
423
424 /* for total duration */
425 UINT8_TO_STREAM (p, NFC_PMID_TOTAL_DURATION);
426 UINT8_TO_STREAM (p, NCI_PARAM_LEN_TOTAL_DURATION);
427 UINT16_TO_STREAM (p, nfa_dm_cb.disc_cb.disc_duration);
428
429 if (p > params)
430 {
431 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
432 }
433}
434
435/*******************************************************************************
436**
437** Function nfa_dm_set_rf_listen_mode_raw_config
438**
439** Description Set raw listen parameters
440**
441** Returns void
442**
443*******************************************************************************/
444static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask)
445{
446 tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
447 tNFA_LISTEN_CFG *p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
448 UINT8 params[250], *p, xx;
449
450 NFA_TRACE_DEBUG0 ("nfa_dm_set_rf_listen_mode_raw_config ()");
451
452 /*
453 ** Discovery Configuration Parameters for Listen A
454 */
455 if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] == NFA_DM_DISC_HOST_ID_DH)
456 &&(p_cfg->la_enable) )
457 {
458 p = params;
459
460 UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
461 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
462 UINT8_TO_STREAM (p, p_cfg->la_bit_frame_sdd);
463
464 UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
465 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
466 UINT8_TO_STREAM (p, p_cfg->la_platform_config);
467
468 UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
469 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_SEL_INFO);
470 UINT8_TO_STREAM (p, p_cfg->la_sel_info);
471
472 if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T)
473 {
474 disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
475 }
476 else
477 {
478 /* If T4T or NFCDEP */
479 if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP)
480 {
481 disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
482 }
483
484 if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP)
485 {
486 disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
487 }
488
489 /* If neither, T4T nor NFCDEP, then its T2T */
490 if (disc_mask == 0)
491 {
492 disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
493 }
494 }
495
496 UINT8_TO_STREAM (p, NFC_PMID_LA_NFCID1);
497 UINT8_TO_STREAM (p, p_cfg->la_nfcid1_len);
498 ARRAY_TO_STREAM (p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
499
500 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
501 }
502
503 /*
504 ** Discovery Configuration Parameters for Listen B
505 */
506 if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] == NFA_DM_DISC_HOST_ID_DH)
507 &&(p_cfg->lb_enable) )
508 {
509 p = params;
510
511 UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
512 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_SENSB_INFO);
513 UINT8_TO_STREAM (p, p_cfg->lb_sensb_info);
514
515 UINT8_TO_STREAM (p, NFC_PMID_LB_NFCID0);
516 UINT8_TO_STREAM (p, p_cfg->lb_nfcid0_len);
517 ARRAY_TO_STREAM (p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
518
519 UINT8_TO_STREAM (p, NFC_PMID_LB_APPDATA);
520 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_APPDATA);
521 ARRAY_TO_STREAM (p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
522
523 UINT8_TO_STREAM (p, NFC_PMID_LB_SFGI);
524 UINT8_TO_STREAM (p, 1);
525 UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
526
527 UINT8_TO_STREAM (p, NFC_PMID_LB_ADC_FO);
528 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_ADC_FO);
529 UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
530
531 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
532
533 if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP)
534 {
535 disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
536 }
537 }
538
539 /*
540 ** Discovery Configuration Parameters for Listen F
541 */
542 if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] == NFA_DM_DISC_HOST_ID_DH)
543 &&(p_cfg->lf_enable) )
544 {
545 p = params;
546
547 UINT8_TO_STREAM (p, NFC_PMID_LF_CON_BITR_F);
548 UINT8_TO_STREAM (p, 1);
549 UINT8_TO_STREAM (p, p_cfg->lf_con_bitr_f);
550
551 UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
552 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_PROTOCOL);
553 UINT8_TO_STREAM (p, p_cfg->lf_protocol_type);
554
555 UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_FLAGS2);
556 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
557 UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
558
559 /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be ignored */
560 for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++)
561 {
562 if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000)
563 {
564 UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_ID1 + xx);
565 UINT8_TO_STREAM (p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
566 ARRAY_TO_STREAM (p, p_cfg->lf_t3t_identifier[xx], NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
567 }
568 }
569
570 UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_PMM);
571 UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_T3T_PMM);
572 ARRAY_TO_STREAM (p, p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
573
574 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
575
576 if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED)
577 {
578 disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
579 }
580 if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP)
581 {
582 disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
583 }
584 }
585
586 /*
587 ** Discovery Configuration Parameters for Listen ISO-DEP
588 */
589 if ((disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LB_ISO_DEP))
590 &&(p_cfg->li_enable))
591 {
592 p = params;
593
594 UINT8_TO_STREAM (p, NFC_PMID_FWI);
595 UINT8_TO_STREAM (p, NCI_PARAM_LEN_FWI);
596 UINT8_TO_STREAM (p, p_cfg->li_fwi);
597
598 if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)
599 {
600 UINT8_TO_STREAM (p, NFC_PMID_LA_HIST_BY);
601 UINT8_TO_STREAM (p, p_cfg->la_hist_bytes_len);
602 ARRAY_TO_STREAM (p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
603 }
604
605 if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
606 {
607 UINT8_TO_STREAM (p, NFC_PMID_LB_H_INFO);
608 UINT8_TO_STREAM (p, p_cfg->lb_h_info_resp_len);
609 ARRAY_TO_STREAM (p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
610 }
611
612 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
613 }
614
615 /*
616 ** Discovery Configuration Parameters for Listen NFC-DEP
617 */
618 if ( (disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP|NFA_DM_DISC_MASK_LF_NFC_DEP))
619 &&(p_cfg->ln_enable))
620 {
621 p = params;
622
623 UINT8_TO_STREAM (p, NFC_PMID_WT);
624 UINT8_TO_STREAM (p, NCI_PARAM_LEN_WT);
625 UINT8_TO_STREAM (p, p_cfg->ln_wt);
626
627 UINT8_TO_STREAM (p, NFC_PMID_ATR_RES_GEN_BYTES);
628 UINT8_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes_len);
629 ARRAY_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes, p_cfg->ln_atr_res_gen_bytes_len);
630
631 UINT8_TO_STREAM (p, NFC_PMID_ATR_RSP_CONFIG);
632 UINT8_TO_STREAM (p, 1);
633 UINT8_TO_STREAM (p, p_cfg->ln_atr_res_config);
634
635 nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
636 }
637
638 *p_disc_mask = disc_mask;
639
640 NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_raw_config () disc_mask = 0x%x", disc_mask);
641}
642
643/*******************************************************************************
644**
645** Function nfa_dm_disc_get_disc_mask
646**
647** Description Convert RF technology, mode and protocol to bit mask
648**
649** Returns tNFA_DM_DISC_TECH_PROTO_MASK
650**
651*******************************************************************************/
652static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
653 tNFC_PROTOCOL protocol)
654{
655 /* Set initial disc_mask to legacy poll or listen */
656 tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY : NFA_DM_DISC_MASK_P_LEGACY);
657
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700658 if (NFC_DISCOVERY_TYPE_POLL_A == tech_n_mode)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800659 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800660 switch (protocol)
661 {
662 case NFC_PROTOCOL_T1T:
663 disc_mask = NFA_DM_DISC_MASK_PA_T1T;
664 break;
665 case NFC_PROTOCOL_T2T:
666 disc_mask = NFA_DM_DISC_MASK_PA_T2T;
667 break;
668 case NFC_PROTOCOL_ISO_DEP:
669 disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
670 break;
671 case NFC_PROTOCOL_NFC_DEP:
672 disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
673 break;
674 }
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700675 }
676 else if (NFC_DISCOVERY_TYPE_POLL_B == tech_n_mode)
677 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800678 if (protocol == NFC_PROTOCOL_ISO_DEP)
679 disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700680 }
681 else if (NFC_DISCOVERY_TYPE_POLL_F == tech_n_mode)
682 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800683 if (protocol == NFC_PROTOCOL_T3T)
684 disc_mask = NFA_DM_DISC_MASK_PF_T3T;
685 else if (protocol == NFC_PROTOCOL_NFC_DEP)
686 disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700687 }
688 else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == tech_n_mode)
689 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800690 disc_mask = NFA_DM_DISC_MASK_P_ISO15693;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700691 }
692 else if (NFC_DISCOVERY_TYPE_POLL_B_PRIME == tech_n_mode)
693 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800694 disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700695 }
696 else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == tech_n_mode)
697 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800698 disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700699 }
700 else if (NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == tech_n_mode)
701 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800702 disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700703 }
704 else if (NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == tech_n_mode)
705 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800706 disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700707 }
708 else if (NFC_DISCOVERY_TYPE_LISTEN_A == tech_n_mode)
709 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800710 switch (protocol)
711 {
712 case NFC_PROTOCOL_T1T:
713 disc_mask = NFA_DM_DISC_MASK_LA_T1T;
714 break;
715 case NFC_PROTOCOL_T2T:
716 disc_mask = NFA_DM_DISC_MASK_LA_T2T;
717 break;
718 case NFC_PROTOCOL_ISO_DEP:
719 disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
720 break;
721 case NFC_PROTOCOL_NFC_DEP:
722 disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
723 break;
724 }
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700725 }
726 else if (NFC_DISCOVERY_TYPE_LISTEN_B == tech_n_mode)
727 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800728 if (protocol == NFC_PROTOCOL_ISO_DEP)
729 disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700730 }
731 else if (NFC_DISCOVERY_TYPE_LISTEN_F == tech_n_mode)
732 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800733 if (protocol == NFC_PROTOCOL_T3T)
734 disc_mask = NFA_DM_DISC_MASK_LF_T3T;
735 else if (protocol == NFC_PROTOCOL_NFC_DEP)
736 disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700737 }
738 else if (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == tech_n_mode)
739 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800740 disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700741 }
742 else if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == tech_n_mode)
743 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800744 disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700745 }
746 else if (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == tech_n_mode)
747 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800748 disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
Jizhou Liaoacf1ec02015-06-30 10:25:41 -0700749 }
750 else if (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == tech_n_mode)
751 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800752 disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800753 }
754
755 NFA_TRACE_DEBUG3 ("nfa_dm_disc_get_disc_mask (): tech_n_mode:0x%X, protocol:0x%X, disc_mask:0x%X",
756 tech_n_mode, protocol, disc_mask);
757 return (disc_mask);
758}
759
760/*******************************************************************************
761**
762** Function nfa_dm_disc_discovery_cback
763**
764** Description Discovery callback event from NFC
765**
766** Returns void
767**
768*******************************************************************************/
769static void nfa_dm_disc_discovery_cback (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data)
770{
771 tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
772
773 NFA_TRACE_DEBUG1 ("nfa_dm_disc_discovery_cback (): event:0x%X", event);
774
775 switch (event)
776 {
777 case NFC_START_DEVT:
778 dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
779 break;
780 case NFC_RESULT_DEVT:
781 dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
782 break;
783 case NFC_SELECT_DEVT:
784 dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
785 break;
786 case NFC_ACTIVATE_DEVT:
787 dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
788 break;
789 case NFC_DEACTIVATE_DEVT:
790 if (p_data->deactivate.is_ntf)
Evan Chua24be4f2013-11-13 15:30:16 -0500791 {
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800792 dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
Evan Chua24be4f2013-11-13 15:30:16 -0500793 if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) || (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY))
794 {
795 NFC_SetReassemblyFlag (TRUE);
796 nfa_dm_cb.flags &= ~NFA_DM_FLAGS_RAW_FRAME;
797 }
798 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800799 else
800 dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
801 break;
802 default:
803 NFA_TRACE_ERROR0 ("Unexpected event");
804 return;
805 }
806
807 nfa_dm_disc_sm_execute (dm_disc_event, (tNFA_DM_RF_DISC_DATA *) p_data);
808}
809
810/*******************************************************************************
811**
812** Function nfa_dm_disc_notify_started
813**
814** Description Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
815** NFA_RF_DISCOVERY_STARTED_EVT, if needed
816**
817** Returns void
818**
819*******************************************************************************/
820static void nfa_dm_disc_notify_started (tNFA_STATUS status)
821{
822 tNFA_CONN_EVT_DATA evt_data;
823
824 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
825 {
826 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
827
828 evt_data.status = status;
829
830 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
831 nfa_dm_conn_cback_event_notify (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &evt_data);
832 else
833 nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
834 }
835}
836
837/*******************************************************************************
838**
839** Function nfa_dm_disc_conn_event_notify
840**
841** Description Notify application of CONN_CBACK event, using appropriate
842** callback
843**
844** Returns nothing
845**
846*******************************************************************************/
847void nfa_dm_disc_conn_event_notify (UINT8 event, tNFA_STATUS status)
848{
849 tNFA_CONN_EVT_DATA evt_data;
850
851 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
852 {
853 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
854 evt_data.status = status;
855
856 if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
857 {
858 /* Use exclusive RF mode callback */
859 if (nfa_dm_cb.p_excl_conn_cback)
860 (*nfa_dm_cb.p_excl_conn_cback) (event, &evt_data);
861 }
862 else
863 {
864 (*nfa_dm_cb.p_conn_cback) (event, &evt_data);
865 }
866 }
867}
868
869/*******************************************************************************
870**
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700871** Function nfa_dm_disc_force_to_idle
872**
873** Description Force NFCC to idle state while waiting for deactivation NTF
874**
875** Returns tNFC_STATUS
876**
877*******************************************************************************/
878static tNFC_STATUS nfa_dm_disc_force_to_idle (void)
879{
880 tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
881
882 NFA_TRACE_DEBUG1 ("nfa_dm_disc_force_to_idle() disc_flags = 0x%x", nfa_dm_cb.disc_cb.disc_flags);
883
884 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) /* do not execute more than one */
885 {
886 nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
887 nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
888 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
889 status = NFC_Deactivate (NFC_DEACTIVATE_TYPE_IDLE);
890 }
891
892 return (status);
893}
894
895/*******************************************************************************
896**
897** Function nfa_dm_disc_deact_ntf_timeout_cback
898**
899** Description Timeout while waiting for deactivation NTF
900**
901** Returns void
902**
903*******************************************************************************/
904static void nfa_dm_disc_deact_ntf_timeout_cback (TIMER_LIST_ENT *p_tle)
905{
906 NFA_TRACE_ERROR0 ("nfa_dm_disc_deact_ntf_timeout_cback()");
907
908 nfa_dm_disc_force_to_idle();
909}
910
911/*******************************************************************************
912**
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800913** Function nfa_dm_send_deactivate_cmd
914**
915** Description Send deactivate command to NFCC, if needed.
916**
917** Returns NFC_STATUS_OK - deactivate cmd is sent
918** NCI_STATUS_FAILED - no buffers
919** NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
920** to send deactivate cmd
921**
922*******************************************************************************/
923static tNFC_STATUS nfa_dm_send_deactivate_cmd (tNFC_DEACT_TYPE deactivate_type)
924{
925 tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
926 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);
927
928 if (!w4_flags)
929 {
930 /* if deactivate CMD was not sent to NFCC */
931 nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
932
933 status = NFC_Deactivate (deactivate_type);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700934
935 if (!nfa_dm_cb.disc_cb.tle.in_use)
936 {
937 nfa_dm_cb.disc_cb.tle.p_cback = (TIMER_CBACK *)nfa_dm_disc_deact_ntf_timeout_cback;
938 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.tle, 0, NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF);
939 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800940 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700941 else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800942 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -0700943 if (deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP)
944 {
945 status = NFC_STATUS_SEMANTIC_ERROR;
946 }
947 else if (nfa_dm_cb.disc_cb.tle.in_use)
948 {
949 status = NFC_STATUS_OK;
950 }
951 else
952 {
953 status = nfa_dm_disc_force_to_idle ();
954 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -0800955 }
956
957 return status;
958}
959
960/*******************************************************************************
961**
962** Function nfa_dm_start_rf_discover
963**
964** Description Start RF discovery
965**
966** Returns void
967**
968*******************************************************************************/
969void nfa_dm_start_rf_discover (void)
970{
971 tNFC_DISCOVER_PARAMS disc_params[NFA_DM_MAX_DISC_PARAMS];
972 tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0, poll_mask, listen_mask;
973 UINT8 num_params, xx;
974
975 NFA_TRACE_DEBUG0 ("nfa_dm_start_rf_discover ()");
976 /* Make sure that RF discovery was enabled, or some app has exclusive control */
977 if ( (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED))
978 &&(nfa_dm_cb.disc_cb.excl_disc_entry.in_use == FALSE) )
979 {
980 return;
981 }
982
983 /* get listen mode routing table for technology */
984 nfa_ee_get_tech_route (NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
985
986 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
987 {
988 nfa_dm_set_rf_listen_mode_raw_config (&dm_disc_mask);
989 dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask & NFA_DM_DISC_MASK_POLL);
990 nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
991 }
992 else
993 {
994 /* Collect RF discovery request from sub-modules */
995 for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
996 {
997 if (nfa_dm_cb.disc_cb.entry[xx].in_use)
998 {
999 poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_POLL);
1000
1001 /* clear poll mode technolgies and protocols which are already used by others */
1002 poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
1003
1004 listen_mask = 0;
1005
1006 /*
1007 ** add listen mode technolgies and protocols if host ID is matched to listen mode routing table
1008 */
1009
1010 /* NFC-A */
1011 if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A])
1012 {
1013 listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
1014 & ( NFA_DM_DISC_MASK_LA_T1T
1015 |NFA_DM_DISC_MASK_LA_T2T
1016 |NFA_DM_DISC_MASK_LA_ISO_DEP
1017 |NFA_DM_DISC_MASK_LA_NFC_DEP
1018 |NFA_DM_DISC_MASK_LAA_NFC_DEP );
1019 }
1020 else
1021 {
1022 /* host can listen ISO-DEP based on AID routing */
1023 listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP);
Evan Chu85b7e842013-01-18 11:02:50 -05001024
1025 /* host can listen NFC-DEP based on protocol routing */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001026 listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_LA_NFC_DEP);
1027 listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP);
1028 }
1029
1030 /* NFC-B */
1031 /* multiple hosts can listen ISO-DEP based on AID routing */
1032 listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
1033 & NFA_DM_DISC_MASK_LB_ISO_DEP;
1034
1035 /* NFC-F */
Evan Chu7c69b272013-05-14 12:48:36 -04001036 /* NFCC can support NFC-DEP and T3T listening based on NFCID routing regardless of NFC-F tech routing */
1037 listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
1038 & ( NFA_DM_DISC_MASK_LF_T3T
1039 |NFA_DM_DISC_MASK_LF_NFC_DEP
1040 |NFA_DM_DISC_MASK_LFA_NFC_DEP );
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001041
1042 /* NFC-B Prime */
1043 if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP])
1044 {
1045 listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
1046 & NFA_DM_DISC_MASK_L_B_PRIME;
1047 }
1048
1049 /*
1050 ** clear listen mode technolgies and protocols which are already used by others
1051 */
1052
1053 /* Check if other modules are listening T1T or T2T */
1054 if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T))
1055 {
1056 listen_mask &= ~( NFA_DM_DISC_MASK_LA_T1T
1057 |NFA_DM_DISC_MASK_LA_T2T
1058 |NFA_DM_DISC_MASK_LA_ISO_DEP
1059 |NFA_DM_DISC_MASK_LA_NFC_DEP );
1060 }
1061
1062 /* T1T/T2T has priority on NFC-A */
1063 if ( (dm_disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP))
1064 &&(listen_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T)))
1065 {
1066 dm_disc_mask &= ~( NFA_DM_DISC_MASK_LA_ISO_DEP
1067 |NFA_DM_DISC_MASK_LA_NFC_DEP );
1068 }
1069
1070 /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based on AID routing */
1071
1072 /* Check if other modules are listening NFC-DEP */
1073 if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP))
1074 {
1075 listen_mask &= ~( NFA_DM_DISC_MASK_LA_NFC_DEP
1076 |NFA_DM_DISC_MASK_LAA_NFC_DEP );
1077 }
1078
1079 nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask = poll_mask | listen_mask;
1080
1081 NFA_TRACE_DEBUG2 ("nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x",
1082 xx, nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
1083
1084 dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
1085 }
1086 }
1087
1088 /* Let P2P set GEN bytes for LLCP to NFCC */
Evan Chua24be4f2013-11-13 15:30:16 -05001089 if (dm_disc_mask & NFA_DM_DISC_MASK_NFC_DEP)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001090 {
1091 nfa_p2p_set_config (dm_disc_mask);
1092 }
1093 }
1094
1095 NFA_TRACE_DEBUG1 ("dm_disc_mask = 0x%x", dm_disc_mask);
1096
1097 /* Get Discovery Technology parameters */
1098 num_params = nfa_dm_get_rf_discover_config (dm_disc_mask, disc_params, NFA_DM_MAX_DISC_PARAMS);
1099
1100 if (num_params)
1101 {
1102 /*
1103 ** NFCC will abort programming personality slots if not available.
1104 ** NFCC programs the personality slots in the following order of RF technologies:
1105 ** NFC-A, NFC-B, NFC-BP, NFC-I93
1106 */
1107
1108 /* if this is not for exclusive control */
1109 if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1110 {
1111 /* update listening protocols in each NFC technology */
1112 nfa_dm_set_rf_listen_mode_config (dm_disc_mask);
1113 }
1114
1115 /* Set polling duty cycle */
1116 nfa_dm_set_total_duration ();
1117 nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
1118
1119 NFC_DiscoveryStart (num_params, disc_params, nfa_dm_disc_discovery_cback);
1120 /* set flag about waiting for response in IDLE state */
1121 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1122
1123 /* register callback to get interface error NTF */
1124 NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
1125 }
1126 else
1127 {
1128 /* RF discovery is started but there is no valid technology or protocol to discover */
1129 nfa_dm_disc_notify_started (NFA_STATUS_OK);
1130 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001131
Evan Chu7c69b272013-05-14 12:48:36 -04001132 /* if Kovio presence check timer is running, timeout callback will reset the activation information */
1133 if ( (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO)
1134 ||(!nfa_dm_cb.disc_cb.kovio_tle.in_use) )
1135 {
1136 /* reset protocol and hanlde of activated sub-module */
1137 nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1138 nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1139 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001140}
1141
1142/*******************************************************************************
1143**
1144** Function nfa_dm_notify_discovery
1145**
1146** Description Send RF discovery notification to upper layer
1147**
1148** Returns void
1149**
1150*******************************************************************************/
1151static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data)
1152{
1153 tNFA_CONN_EVT_DATA conn_evt;
1154
1155 /* let application select a device */
1156 conn_evt.disc_result.status = NFA_STATUS_OK;
1157 memcpy (&(conn_evt.disc_result.discovery_ntf),
1158 &(p_data->nfc_discover.result),
1159 sizeof (tNFC_RESULT_DEVT));
1160
1161 nfa_dm_conn_cback_event_notify (NFA_DISC_RESULT_EVT, &conn_evt);
1162}
1163
Evan Chu7c69b272013-05-14 12:48:36 -04001164
1165/*******************************************************************************
1166**
1167** Function nfa_dm_disc_handle_kovio_activation
1168**
1169** Description Handle Kovio activation; whether it's new or repeated activation
1170**
1171** Returns TRUE if repeated activation. No need to notify activated event to upper layer
1172**
1173*******************************************************************************/
1174BOOLEAN nfa_dm_disc_handle_kovio_activation (tNFC_DISCOVER *p_data, tNFA_DISCOVER_CBACK *p_disc_cback)
1175{
1176 tNFC_DISCOVER disc_data;
1177
1178 if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
1179 {
1180 /* if this is new Kovio bar code tag */
1181 if ( (nfa_dm_cb.activated_nfcid_len != p_data->activate.rf_tech_param.param.pk.uid_len)
1182 ||(memcmp (p_data->activate.rf_tech_param.param.pk.uid,
1183 nfa_dm_cb.activated_nfcid, nfa_dm_cb.activated_nfcid_len)))
1184 {
1185 NFA_TRACE_DEBUG0 ("new Kovio tag is detected");
1186
1187 /* notify presence check failure for previous tag, if presence check is pending */
1188 nfa_dm_disc_report_kovio_presence_check (NFA_STATUS_FAILED);
1189
1190 /* notify deactivation of previous activation before notifying new activation */
1191 if (p_disc_cback)
1192 {
1193 disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1194 (*(p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1195 }
1196
1197 /* restart timer */
1198 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1199 }
1200 else
1201 {
1202 /* notify presence check ok, if presence check is pending */
1203 nfa_dm_disc_report_kovio_presence_check (NFC_STATUS_OK);
1204
1205 /* restart timer and do not notify upper layer */
1206 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1207 return (TRUE);
1208 }
1209 }
1210 else
1211 {
1212 /* this is the first activation, so start timer and notify upper layer */
1213 nfa_dm_cb.disc_cb.kovio_tle.p_cback = (TIMER_CBACK *)nfa_dm_disc_kovio_timeout_cback;
1214 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1215 }
1216
1217 return (FALSE);
1218}
1219
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001220/*******************************************************************************
1221**
1222** Function nfa_dm_disc_notify_activation
1223**
1224** Description Send RF activation notification to sub-module
1225**
1226** Returns NFA_STATUS_OK if success
1227**
1228*******************************************************************************/
1229static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data)
1230{
1231 UINT8 xx, host_id_in_LRT;
1232 UINT8 iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
1233
1234 tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
1235 tNFC_PROTOCOL protocol = p_data->activate.protocol;
1236
1237 tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
1238
1239 NFA_TRACE_DEBUG2 ("nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
1240 tech_n_mode, protocol);
1241
1242 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1243 {
1244 nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1245 nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1246 nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1247 nfa_dm_cb.disc_cb.activated_protocol = protocol;
1248 nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1249
Evan Chu7c69b272013-05-14 12:48:36 -04001250 if (protocol == NFC_PROTOCOL_KOVIO)
1251 {
1252 /* check whether it's new or repeated activation */
1253 if (nfa_dm_disc_handle_kovio_activation (p_data, nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))
1254 {
1255 /* do not notify activation of Kovio to upper layer */
1256 return (NFA_STATUS_OK);
1257 }
1258 }
1259
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001260 if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1261 (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1262
1263 return (NFA_STATUS_OK);
1264 }
1265
1266 /* if this is NFCEE direct RF interface, notify activation to whoever listening UICC */
1267 if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
1268 {
1269 for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1270 {
1271 if ( (nfa_dm_cb.disc_cb.entry[xx].in_use)
1272 &&(nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH))
1273 {
1274 nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1275 nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1276 nfa_dm_cb.disc_cb.activated_protocol = NFC_PROTOCOL_UNKNOWN;
1277 nfa_dm_cb.disc_cb.activated_handle = xx;
1278
1279 NFA_TRACE_DEBUG2 ("activated_rf_interface:0x%x, activated_handle: 0x%x",
1280 nfa_dm_cb.disc_cb.activated_rf_interface,
1281 nfa_dm_cb.disc_cb.activated_handle);
1282
1283 if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1284 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1285
1286 return (NFA_STATUS_OK);
1287 }
1288 }
1289 return (NFA_STATUS_FAILED);
1290 }
1291
1292 /* get bit mask of technolgies/mode and protocol */
1293 activated_disc_mask = nfa_dm_disc_get_disc_mask (tech_n_mode, protocol);
1294
1295 /* get host ID of technology from listen mode routing table */
1296 if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1297 {
1298 host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
1299 }
1300 else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1301 {
1302 host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
1303 }
1304 else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1305 {
1306 host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
1307 }
1308 else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
1309 {
1310 host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
1311 }
1312 else /* DH only */
1313 {
1314 host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1315 }
1316
Evan Chu85b7e842013-01-18 11:02:50 -05001317 if (protocol == NFC_PROTOCOL_NFC_DEP)
1318 {
1319 /* Force NFC-DEP to the host */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001320 host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
1321 }
1322
1323 for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1324 {
1325 /* if any matching NFC technology and protocol */
1326 if (nfa_dm_cb.disc_cb.entry[xx].in_use)
1327 {
1328 if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT)
1329 {
1330 if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & activated_disc_mask)
1331 break;
1332 }
1333 else
1334 {
1335 /* check ISO-DEP listening even if host in LRT is not matched */
1336 if (protocol == NFC_PROTOCOL_ISO_DEP)
1337 {
1338 if ( (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
1339 &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP))
1340 {
1341 iso_dep_t3t__listen = xx;
1342 }
1343 else if ( (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
1344 &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP))
1345 {
1346 iso_dep_t3t__listen = xx;
1347 }
1348 }
1349 /* check T3T listening even if host in LRT is not matched */
1350 else if (protocol == NFC_PROTOCOL_T3T)
1351 {
1352 if ( (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
1353 &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LF_T3T))
1354 {
1355 iso_dep_t3t__listen = xx;
1356 }
1357 }
1358 }
1359 }
1360 }
1361
1362 if (xx >= NFA_DM_DISC_NUM_ENTRIES)
1363 {
1364 /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
1365 xx = iso_dep_t3t__listen;
1366 }
1367
1368 if (xx < NFA_DM_DISC_NUM_ENTRIES)
1369 {
1370 nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
1371 nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
1372 nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
1373 nfa_dm_cb.disc_cb.activated_protocol = protocol;
1374 nfa_dm_cb.disc_cb.activated_handle = xx;
1375
1376 NFA_TRACE_DEBUG2 ("activated_protocol:0x%x, activated_handle: 0x%x",
1377 nfa_dm_cb.disc_cb.activated_protocol,
1378 nfa_dm_cb.disc_cb.activated_handle);
1379
Evan Chu7c69b272013-05-14 12:48:36 -04001380 if (protocol == NFC_PROTOCOL_KOVIO)
1381 {
1382 /* check whether it's new or repeated activation */
1383 if (nfa_dm_disc_handle_kovio_activation (p_data, nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))
1384 {
1385 /* do not notify activation of Kovio to upper layer */
1386 return (NFA_STATUS_OK);
1387 }
1388 }
1389
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001390 if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1391 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
1392
1393 return (NFA_STATUS_OK);
1394 }
1395 else
1396 {
1397 nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
1398 nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
1399 return (NFA_STATUS_FAILED);
1400 }
1401}
1402
1403/*******************************************************************************
1404**
1405** Function nfa_dm_disc_notify_deactivation
1406**
1407** Description Send deactivation notification to sub-module
1408**
1409** Returns None
1410**
1411*******************************************************************************/
1412static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event,
1413 tNFC_DISCOVER *p_data)
1414{
1415 tNFA_HANDLE xx;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001416 tNFA_CONN_EVT_DATA evt_data;
1417 tNFC_DISCOVER disc_data;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001418
1419 NFA_TRACE_DEBUG1 ("nfa_dm_disc_notify_deactivation (): activated_handle=%d",
1420 nfa_dm_cb.disc_cb.activated_handle);
1421
1422 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
1423 {
Evan Chuc95c79c2013-04-12 17:38:09 -04001424 NFA_TRACE_DEBUG0 ("nfa_dm_disc_notify_deactivation (): for sleep wakeup");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001425 return;
1426 }
1427
1428 if (sm_event == NFA_DM_RF_DEACTIVATE_RSP)
1429 {
1430 /*
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001431 ** Activation has been aborted by upper layer in NFA_DM_RFST_W4_ALL_DISCOVERIES or NFA_DM_RFST_W4_HOST_SELECT
1432 ** Deactivation by upper layer or RF link loss in NFA_DM_RFST_LISTEN_SLEEP
1433 ** No sub-module is activated at this state.
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001434 */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001435
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001436 if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_SLEEP)
1437 {
1438 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1439 {
1440 if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1441 {
1442 disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1443 (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1444 }
1445 }
1446 else
1447 {
1448 /* let each sub-module handle deactivation */
1449 for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1450 {
1451 if ( (nfa_dm_cb.disc_cb.entry[xx].in_use)
1452 &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LISTEN) )
1453 {
1454 disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1455 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
1456 }
1457 }
1458 }
1459 }
Evan Chudf5080d2013-06-14 13:57:47 -04001460 else if ( (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING))
1461 ||(nfa_dm_cb.disc_cb.deact_notify_pending) )
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001462 {
Evan Chu7c69b272013-05-14 12:48:36 -04001463 xx = nfa_dm_cb.disc_cb.activated_handle;
1464
1465 /* notify event to activated module if failed while reactivation */
1466 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1467 {
1468 if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1469 {
1470 disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1471 (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1472 }
1473 }
1474 else if ( (xx < NFA_DM_DISC_NUM_ENTRIES)
1475 &&(nfa_dm_cb.disc_cb.entry[xx].in_use)
1476 &&(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback) )
1477 {
1478 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1479 }
1480 else
1481 {
1482 /* notify deactivation to application if there is no activated module */
1483 evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1484 nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
1485 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001486 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001487 }
1488 else
1489 {
Evan Chu7c69b272013-05-14 12:48:36 -04001490 if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO)
1491 {
1492 if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
1493 {
1494 /* restart timer and do not notify upper layer */
1495 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1496 return;
1497 }
1498 /* Otherwise, upper layer initiated deactivation. */
1499 }
1500
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001501 /* notify event to activated module */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001502 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001503 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001504 if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1505 {
1506 disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
1507 (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1508 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001509 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001510 else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001511 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001512 xx = nfa_dm_cb.disc_cb.activated_handle;
1513
1514 if ((xx < NFA_DM_DISC_NUM_ENTRIES) && (nfa_dm_cb.disc_cb.entry[xx].in_use))
1515 {
1516 if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1517 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
1518 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001519 }
1520 }
1521
1522 /* clear activated information */
1523 nfa_dm_cb.disc_cb.activated_tech_mode = 0;
1524 nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
1525 nfa_dm_cb.disc_cb.activated_rf_interface = 0;
1526 nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001527 nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
Evan Chudf5080d2013-06-14 13:57:47 -04001528 nfa_dm_cb.disc_cb.deact_notify_pending = FALSE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001529}
1530
1531/*******************************************************************************
1532**
Evan Chuc95c79c2013-04-12 17:38:09 -04001533** Function nfa_dm_disc_sleep_wakeup
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001534**
Evan Chuc95c79c2013-04-12 17:38:09 -04001535** Description Put tag to sleep, then wake it up. Can be used Perform
1536** legacy presence check or to wake up tag that went to HALT
1537** state
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001538**
1539** Returns TRUE if operation started
1540**
1541*******************************************************************************/
Evan Chuc95c79c2013-04-12 17:38:09 -04001542tNFC_STATUS nfa_dm_disc_sleep_wakeup (void)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001543{
1544 tNFC_STATUS status = NFC_STATUS_FAILED;
1545
1546 if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
1547 {
1548 /* Deactivate to sleep mode */
1549 status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
1550 if (status == NFC_STATUS_OK)
1551 {
Evan Chuc95c79c2013-04-12 17:38:09 -04001552 /* deactivate to sleep is sent on behalf of sleep wakeup.
1553 * set the sleep wakeup information in control block */
Evan Chu7c69b272013-05-14 12:48:36 -04001554 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1555 nfa_dm_cb.disc_cb.deact_pending = FALSE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001556 }
1557 }
1558
1559 return (status);
1560}
1561
1562/*******************************************************************************
1563**
Evan Chua24be4f2013-11-13 15:30:16 -05001564** Function nfa_dm_is_raw_frame_session
1565**
1566** Description If NFA_SendRawFrame is called since RF activation,
1567** this function returns TRUE.
1568**
1569** Returns TRUE if NFA_SendRawFrame is called
1570**
1571*******************************************************************************/
1572BOOLEAN nfa_dm_is_raw_frame_session (void)
1573{
1574 return ((nfa_dm_cb.flags & NFA_DM_FLAGS_RAW_FRAME) ? TRUE : FALSE);
1575}
1576
1577/*******************************************************************************
1578**
Evan Chu67aef6c2013-08-29 13:02:54 -07001579** Function nfa_dm_is_p2p_paused
1580**
1581** Description If NFA_PauseP2p is called sand still effective,
1582** this function returns TRUE.
1583**
1584** Returns TRUE if NFA_SendRawFrame is called
1585**
1586*******************************************************************************/
1587BOOLEAN nfa_dm_is_p2p_paused (void)
1588{
1589 return ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) ? TRUE : FALSE);
1590}
1591
1592/*******************************************************************************
1593**
Evan Chuc95c79c2013-04-12 17:38:09 -04001594** Function nfa_dm_disc_end_sleep_wakeup
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001595**
Evan Chuc95c79c2013-04-12 17:38:09 -04001596** Description Sleep Wakeup is complete
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001597**
Evan Chuc95c79c2013-04-12 17:38:09 -04001598** Returns None
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001599**
1600*******************************************************************************/
Evan Chuc95c79c2013-04-12 17:38:09 -04001601static void nfa_dm_disc_end_sleep_wakeup (tNFC_STATUS status)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001602{
Evan Chu7c69b272013-05-14 12:48:36 -04001603 if ( (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO)
1604 &&(nfa_dm_cb.disc_cb.kovio_tle.in_use) )
1605 {
1606 /* ignore it while doing Kovio presence check */
1607 return;
1608 }
1609
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001610 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
1611 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001612 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1613
Evan Chuc95c79c2013-04-12 17:38:09 -04001614 /* notify RW module that sleep wakeup is finished */
1615 nfa_rw_handle_sleep_wakeup_rsp (status);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001616
Evan Chu7c69b272013-05-14 12:48:36 -04001617 if (nfa_dm_cb.disc_cb.deact_pending)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001618 {
Evan Chu7c69b272013-05-14 12:48:36 -04001619 nfa_dm_cb.disc_cb.deact_pending = FALSE;
Evan Chudf5080d2013-06-14 13:57:47 -04001620 /* Perform pending deactivate command and on response notfiy deactivation */
1621 nfa_dm_cb.disc_cb.deact_notify_pending = TRUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001622 nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
Evan Chu7c69b272013-05-14 12:48:36 -04001623 (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.disc_cb.pending_deact_type);
1624 }
1625 }
1626}
1627
1628/*******************************************************************************
1629**
1630** Function nfa_dm_disc_kovio_timeout_cback
1631**
1632** Description Timeout for Kovio bar code tag presence check
1633**
1634** Returns void
1635**
1636*******************************************************************************/
1637static void nfa_dm_disc_kovio_timeout_cback (TIMER_LIST_ENT *p_tle)
1638{
1639 tNFC_DEACTIVATE_DEVT deact;
1640
1641 NFA_TRACE_DEBUG0 ("nfa_dm_disc_kovio_timeout_cback()");
1642
1643 /* notify presence check failure, if presence check is pending */
1644 nfa_dm_disc_report_kovio_presence_check (NFC_STATUS_FAILED);
1645
1646 if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
1647 {
1648 /* restart timer in case that upper layer's presence check interval is too long */
1649 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1650 }
1651 else
1652 {
1653 /* notify upper layer deactivated event */
1654 deact.status = NFC_STATUS_OK;
1655 deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
1656 deact.is_ntf = TRUE;
1657 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, (tNFC_DISCOVER*)&deact);
1658 }
1659}
1660
1661/*******************************************************************************
1662**
1663** Function nfa_dm_disc_start_kovio_presence_check
1664**
1665** Description Deactivate to discovery mode and wait for activation
1666**
1667** Returns TRUE if operation started
1668**
1669*******************************************************************************/
1670tNFC_STATUS nfa_dm_disc_start_kovio_presence_check (void)
1671{
1672 tNFC_STATUS status = NFC_STATUS_FAILED;
1673
1674 NFA_TRACE_DEBUG0 ("nfa_dm_disc_start_kovio_presence_check ()");
1675
1676 if ( (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO)
1677 &&(nfa_dm_cb.disc_cb.kovio_tle.in_use) )
1678 {
1679 if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
1680 {
1681 /* restart timer */
1682 nfa_sys_start_timer (&nfa_dm_cb.disc_cb.kovio_tle, 0, NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
1683
1684 /* Deactivate to discovery mode */
1685 status = nfa_dm_send_deactivate_cmd (NFC_DEACTIVATE_TYPE_DISCOVERY);
1686
1687 if (status == NFC_STATUS_OK)
1688 {
1689 /* deactivate to sleep is sent on behalf of sleep wakeup.
1690 * set the sleep wakeup information in control block */
1691 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1692 nfa_dm_cb.disc_cb.deact_pending = FALSE;
1693 }
1694 }
1695 else
1696 {
1697 /* wait for next activation */
1698 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
1699 nfa_dm_cb.disc_cb.deact_pending = FALSE;
1700 status = NFC_STATUS_OK;
1701 }
1702 }
1703
1704 return (status);
1705}
1706
1707/*******************************************************************************
1708**
1709** Function nfa_dm_disc_report_kovio_presence_check
1710**
1711** Description Report Kovio presence check status
1712**
1713** Returns None
1714**
1715*******************************************************************************/
1716static void nfa_dm_disc_report_kovio_presence_check (tNFC_STATUS status)
1717{
1718 NFA_TRACE_DEBUG0 ("nfa_dm_disc_report_kovio_presence_check ()");
1719
1720 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
1721 {
1722 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
1723
1724 /* notify RW module that sleep wakeup is finished */
1725 nfa_rw_handle_presence_check_rsp (status);
1726
1727 if (nfa_dm_cb.disc_cb.deact_pending)
1728 {
1729 nfa_dm_cb.disc_cb.deact_pending = FALSE;
1730 nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
1731 (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.disc_cb.pending_deact_type);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001732 }
1733 }
1734}
1735
1736/*******************************************************************************
1737**
1738** Function nfa_dm_disc_data_cback
1739**
1740** Description Monitoring interface error through data callback
1741**
1742** Returns void
1743**
1744*******************************************************************************/
1745static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
1746{
1747 NFA_TRACE_DEBUG0 ("nfa_dm_disc_data_cback ()");
1748
1749 /* if selection failed */
1750 if (event == NFC_ERROR_CEVT)
1751 {
1752 nfa_dm_disc_sm_execute (NFA_DM_CORE_INTF_ERROR_NTF, NULL);
1753 }
1754 else if (event == NFC_DATA_CEVT)
1755 {
1756 GKI_freebuf (p_data->data.p_data);
1757 }
1758}
1759
1760/*******************************************************************************
1761**
1762** Function nfa_dm_disc_new_state
1763**
1764** Description Processing discovery events in NFA_DM_RFST_IDLE state
1765**
1766** Returns void
1767**
1768*******************************************************************************/
1769void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state)
1770{
1771 tNFA_CONN_EVT_DATA evt_data;
1772 tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
1773
1774#if (BT_TRACE_VERBOSE == TRUE)
1775 NFA_TRACE_DEBUG5 ("nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) disc_flags: 0x%x",
1776 nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
1777 nfa_dm_disc_state_2_str (new_state), new_state, nfa_dm_cb.disc_cb.disc_flags);
1778#else
1779 NFA_TRACE_DEBUG3 ("nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
1780 nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
1781#endif
Evan Chu7c69b272013-05-14 12:48:36 -04001782
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001783 nfa_dm_cb.disc_cb.disc_state = new_state;
Evan Chu7c69b272013-05-14 12:48:36 -04001784
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001785 if ( (new_state == NFA_DM_RFST_IDLE)
1786 &&(!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) ) /* not error recovering */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001787 {
1788 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
1789 {
1790 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
1791
1792 /* if exclusive RF control is stopping */
1793 if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
1794 {
1795 if (old_state > NFA_DM_RFST_DISCOVERY)
1796 {
1797 /* notify deactivation to application */
1798 evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1799 nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
1800 }
1801
1802 nfa_dm_rel_excl_rf_control_and_notify ();
1803 }
1804 else
1805 {
1806 evt_data.status = NFA_STATUS_OK;
1807 nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
1808 }
1809 }
1810 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
1811 {
1812 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
1813 nfa_sys_check_disabled ();
1814 }
1815 }
1816}
1817
1818/*******************************************************************************
1819**
1820** Function nfa_dm_disc_sm_idle
1821**
1822** Description Processing discovery events in NFA_DM_RFST_IDLE state
1823**
1824** Returns void
1825**
1826*******************************************************************************/
1827static void nfa_dm_disc_sm_idle (tNFA_DM_RF_DISC_SM_EVENT event,
1828 tNFA_DM_RF_DISC_DATA *p_data)
1829{
1830 UINT8 xx;
1831
1832 switch (event)
1833 {
1834 case NFA_DM_RF_DISCOVER_CMD:
1835 nfa_dm_start_rf_discover ();
1836 break;
1837
1838 case NFA_DM_RF_DISCOVER_RSP:
1839 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
1840
1841 if (p_data->nfc_discover.status == NFC_STATUS_OK)
1842 {
1843 nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
1844
1845 /* if RF discovery was stopped while waiting for response */
1846 if (nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_STOPPING|NFA_DM_DISC_FLAGS_DISABLING))
1847 {
1848 /* stop discovery */
1849 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1850 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1851 break;
1852 }
1853
1854 if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
1855 {
1856 if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
1857 {
1858 nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
1859
1860 if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
1861 (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
1862 }
1863 }
1864 else
1865 {
1866 /* notify event to each module which is waiting for start */
1867 for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
1868 {
1869 /* if registered module is waiting for starting discovery */
1870 if ( (nfa_dm_cb.disc_cb.entry[xx].in_use)
1871 &&(nfa_dm_cb.disc_cb.dm_disc_mask & nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask)
1872 &&(nfa_dm_cb.disc_cb.entry[xx].disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) )
1873 {
1874 nfa_dm_cb.disc_cb.entry[xx].disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
1875
1876 if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
1877 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
1878 }
1879 }
1880
1881 }
1882 nfa_dm_disc_notify_started (p_data->nfc_discover.status);
1883 }
1884 else
1885 {
1886 /* in rare case that the discovery states of NFCC and DH mismatch and NFCC rejects Discover Cmd
1887 * deactivate idle and then start disvocery when got deactivate rsp */
1888 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1889 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1890 }
1891 break;
1892
1893 case NFA_DM_RF_DEACTIVATE_RSP:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001894 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001895
1896 /* if NFCC goes to idle successfully */
1897 if (p_data->nfc_discover.status == NFC_STATUS_OK)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001898 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001899 /* if DH forced to go idle while waiting for deactivation NTF */
1900 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
1901 {
1902 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
1903
1904 /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or NFA_DM_DISC_FLAGS_DISABLING */
1905 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1906 /* check if need to restart discovery after resync discovery state with NFCC */
1907 nfa_dm_start_rf_discover ();
1908 }
1909 /* Otherwise, deactivating when getting unexpected activation */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001910 }
Jizhou Liao379e7372015-06-03 11:53:38 -07001911 else if (p_data->nfc_discover.status == NCI_STATUS_SEMANTIC_ERROR)
1912 {
1913 /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or NFA_DM_DISC_FLAGS_DISABLING */
1914 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1915 /* check if need to restart discovery after resync discovery state with NFCC */
1916 nfa_dm_start_rf_discover ();
1917 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001918 /* Otherwise, wait for deactivation NTF */
1919 break;
1920
1921 case NFA_DM_RF_DEACTIVATE_NTF:
1922 /* if NFCC sent this after NFCC had rejected deactivate CMD to idle while deactivating */
1923 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
1924 {
1925 if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
1926 {
1927 /* stop discovery */
1928 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1929 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
1930 }
1931 else
1932 {
1933 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
1934 /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or NFA_DM_DISC_FLAGS_DISABLING */
1935 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1936 /* check if need to restart discovery after resync discovery state with NFCC */
1937 nfa_dm_start_rf_discover ();
1938 }
1939 }
1940 /* Otherwise, deactivated when received unexpected activation in idle state */
1941 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
1942 break;
1943
1944 case NFA_DM_RF_INTF_ACTIVATED_NTF:
1945 /* unexpected activation, deactivate to idle */
1946 nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
1947 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001948 break;
1949
1950 case NFA_DM_LP_LISTEN_CMD:
1951 nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
1952 break;
1953
1954 default:
1955 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_idle (): Unexpected discovery event");
1956 break;
1957 }
1958}
1959
1960/*******************************************************************************
1961**
1962** Function nfa_dm_disc_sm_discovery
1963**
1964** Description Processing discovery events in NFA_DM_RFST_DISCOVERY state
1965**
1966** Returns void
1967**
1968*******************************************************************************/
1969static void nfa_dm_disc_sm_discovery (tNFA_DM_RF_DISC_SM_EVENT event,
1970 tNFA_DM_RF_DISC_DATA *p_data)
1971{
1972 switch (event)
1973 {
1974 case NFA_DM_RF_DEACTIVATE_CMD:
1975 /* if deactivate CMD was not sent to NFCC */
1976 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
1977 {
1978 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
1979 NFC_Deactivate (p_data->deactivate_type);
1980 }
1981 break;
1982 case NFA_DM_RF_DEACTIVATE_RSP:
1983 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07001984
1985 /* if it's not race condition between deactivate CMD and activate NTF */
1986 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
1987 {
1988 /* do not notify deactivated to idle in RF discovery state
1989 ** because it is internal or stopping RF discovery
1990 */
1991
1992 /* there was no activation while waiting for deactivation RSP */
1993 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
1994 nfa_dm_start_rf_discover ();
1995 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08001996 break;
1997 case NFA_DM_RF_DISCOVER_NTF:
Jizhou Liao379e7372015-06-03 11:53:38 -07001998 /* Notification Type = NCI_DISCOVER_NTF_LAST_ABORT */
1999 if (p_data->nfc_discover.result.more == NCI_DISCOVER_NTF_LAST_ABORT)
2000 {
2001 /* Fix for multiple tags: After receiving deactivate event, restart discovery */
2002 NFA_TRACE_DEBUG0 ("Received NCI_DISCOVER_NTF_LAST_ABORT, sending deactivate command");
2003 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2004 }
2005 else
2006 {
2007 nfa_dm_disc_new_state (NFA_DM_RFST_W4_ALL_DISCOVERIES);
2008 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002009 nfa_dm_notify_discovery (p_data);
2010 break;
2011 case NFA_DM_RF_INTF_ACTIVATED_NTF:
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002012 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002013 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002014 NFA_TRACE_DEBUG0 ("RF Activated while waiting for deactivation RSP");
2015 /* it's race condition. DH has to wait for deactivation NTF */
2016 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002017 }
2018 else
2019 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002020 if (p_data->nfc_discover.activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
2021 {
2022 nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
2023 }
2024 else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80)
2025 {
2026 /* Listen mode */
2027 nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
2028 }
2029 else
2030 {
2031 /* Poll mode */
2032 nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
2033 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002034
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002035 if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
2036 {
2037 NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002038
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002039 /* after receiving deactivate event, restart discovery */
2040 nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
2041 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2042 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002043 }
2044 break;
2045
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002046 case NFA_DM_RF_DEACTIVATE_NTF:
2047 /* if there was race condition between deactivate CMD and activate NTF */
2048 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)
2049 {
2050 /* race condition is resolved */
2051 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2052
2053 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2054 {
2055 /* do not notify deactivated to idle in RF discovery state
2056 ** because it is internal or stopping RF discovery
2057 */
2058
2059 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2060 nfa_dm_start_rf_discover ();
2061 }
2062 }
2063 break;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002064 case NFA_DM_LP_LISTEN_CMD:
2065 break;
2066 case NFA_DM_CORE_INTF_ERROR_NTF:
2067 break;
2068 default:
2069 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_discovery (): Unexpected discovery event");
2070 break;
2071 }
2072}
2073
2074/*******************************************************************************
2075**
2076** Function nfa_dm_disc_sm_w4_all_discoveries
2077**
2078** Description Processing discovery events in NFA_DM_RFST_W4_ALL_DISCOVERIES state
2079**
2080** Returns void
2081**
2082*******************************************************************************/
2083static void nfa_dm_disc_sm_w4_all_discoveries (tNFA_DM_RF_DISC_SM_EVENT event,
2084 tNFA_DM_RF_DISC_DATA *p_data)
2085{
2086 switch (event)
2087 {
2088 case NFA_DM_RF_DEACTIVATE_CMD:
2089 /* if deactivate CMD was not sent to NFCC */
2090 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2091 {
2092 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
2093 /* only IDLE mode is allowed */
2094 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2095 }
2096 break;
2097 case NFA_DM_RF_DEACTIVATE_RSP:
2098 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002099 /* notify exiting from w4 all discoverie state */
2100 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
2101
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002102 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2103 nfa_dm_start_rf_discover ();
2104 break;
2105 case NFA_DM_RF_DISCOVER_NTF:
Jizhou Liao379e7372015-06-03 11:53:38 -07002106 if(p_data->nfc_discover.result.protocol == NCI_PROTOCOL_UNKNOWN)
2107 {
2108 /* fix for p2p interop issues */
2109 NFA_TRACE_DEBUG0("Unknown protocol - Restart Discovery");
2110 /* after receiving unknown protocol, restart discovery */
2111 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2112 return;
2113 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002114 /* if deactivate CMD is already sent then ignore discover NTF */
2115 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002116 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002117 /* Notification Type = NCI_DISCOVER_NTF_LAST or NCI_DISCOVER_NTF_LAST_ABORT */
2118 if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE)
2119 {
2120 nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
2121 }
2122 nfa_dm_notify_discovery (p_data);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002123 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002124 break;
2125 case NFA_DM_RF_INTF_ACTIVATED_NTF:
2126 /*
2127 ** This is only for ISO15693.
2128 ** FW sends activation NTF when all responses are received from tags without host selecting.
2129 */
2130 nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
2131
2132 if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
2133 {
2134 NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
2135
2136 /* after receiving deactivate event, restart discovery */
2137 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2138 }
2139 break;
2140 default:
2141 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_all_discoveries (): Unexpected discovery event");
2142 break;
2143 }
2144}
2145
2146/*******************************************************************************
2147**
2148** Function nfa_dm_disc_sm_w4_host_select
2149**
2150** Description Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT state
2151**
2152** Returns void
2153**
2154*******************************************************************************/
2155static void nfa_dm_disc_sm_w4_host_select (tNFA_DM_RF_DISC_SM_EVENT event,
2156 tNFA_DM_RF_DISC_DATA *p_data)
2157{
2158 tNFA_CONN_EVT_DATA conn_evt;
Evan Chuc95c79c2013-04-12 17:38:09 -04002159 tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2160 BOOLEAN sleep_wakeup_event = FALSE;
2161 BOOLEAN sleep_wakeup_event_processed = FALSE;
Sherry Smith8adba762014-01-31 13:31:01 -08002162 tNFA_STATUS status;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002163
2164 switch (event)
2165 {
2166 case NFA_DM_RF_DISCOVER_SELECT_CMD:
2167 /* if not waiting to deactivate */
2168 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2169 {
2170 NFC_DiscoverySelect (p_data->select.rf_disc_id,
2171 p_data->select.protocol,
2172 p_data->select.rf_interface);
2173 }
2174 else
2175 {
2176 nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
2177 }
2178 break;
2179
2180 case NFA_DM_RF_DISCOVER_SELECT_RSP:
Evan Chuc95c79c2013-04-12 17:38:09 -04002181 sleep_wakeup_event = TRUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002182 /* notify application status of selection */
2183 if (p_data->nfc_discover.status == NFC_STATUS_OK)
2184 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002185 sleep_wakeup_event_processed = TRUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002186 conn_evt.status = NFA_STATUS_OK;
2187 /* register callback to get interface error NTF */
2188 NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
2189 }
2190 else
2191 conn_evt.status = NFA_STATUS_FAILED;
2192
Evan Chuc95c79c2013-04-12 17:38:09 -04002193 if (!old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002194 {
2195 nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, p_data->nfc_discover.status);
2196 }
2197 break;
2198 case NFA_DM_RF_INTF_ACTIVATED_NTF:
2199 nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
Sherry Smith8adba762014-01-31 13:31:01 -08002200 /* always call nfa_dm_disc_notify_activation to update protocol/interface information in NFA control blocks */
2201 status = nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
Evan Chuc95c79c2013-04-12 17:38:09 -04002202 if (old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002203 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002204 /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag; if deactivation is pending then deactivate */
2205 nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_OK);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002206 }
Sherry Smith8adba762014-01-31 13:31:01 -08002207 else if (status == NFA_STATUS_FAILED)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002208 {
2209 NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
2210
2211 /* after receiving deactivate event, restart discovery */
2212 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2213 }
2214 break;
2215 case NFA_DM_RF_DEACTIVATE_CMD:
Evan Chuc95c79c2013-04-12 17:38:09 -04002216 if (old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002217 {
Evan Chu7c69b272013-05-14 12:48:36 -04002218 nfa_dm_cb.disc_cb.deact_pending = TRUE;
2219 nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002220 }
2221 /* if deactivate CMD was not sent to NFCC */
2222 else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
2223 {
2224 nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
2225 /* only IDLE mode is allowed */
2226 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2227 }
2228 break;
2229 case NFA_DM_RF_DEACTIVATE_RSP:
2230 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002231 /* notify exiting from host select state */
2232 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002233
2234 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2235 nfa_dm_start_rf_discover ();
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002236 break;
2237
2238 case NFA_DM_CORE_INTF_ERROR_NTF:
Evan Chuc95c79c2013-04-12 17:38:09 -04002239 sleep_wakeup_event = TRUE;
2240 if (!old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002241 {
2242 /* target activation failed, upper layer may deactivate or select again */
2243 conn_evt.status = NFA_STATUS_FAILED;
2244 nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
2245 }
2246 break;
2247 default:
2248 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
Jizhou Liao379e7372015-06-03 11:53:38 -07002249 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002250 break;
2251 }
2252
Evan Chuc95c79c2013-04-12 17:38:09 -04002253 if (old_sleep_wakeup_flag && sleep_wakeup_event && !sleep_wakeup_event_processed)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002254 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002255 /* performing sleep wakeup and exception conditions happened
2256 * clear sleep wakeup information and report failure */
2257 nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002258 }
2259}
2260
2261/*******************************************************************************
2262**
2263** Function nfa_dm_disc_sm_poll_active
2264**
2265** Description Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
2266**
2267** Returns void
2268**
2269*******************************************************************************/
2270static void nfa_dm_disc_sm_poll_active (tNFA_DM_RF_DISC_SM_EVENT event,
2271 tNFA_DM_RF_DISC_DATA *p_data)
2272{
2273 tNFC_STATUS status;
Evan Chuc95c79c2013-04-12 17:38:09 -04002274 tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
2275 BOOLEAN sleep_wakeup_event = FALSE;
2276 BOOLEAN sleep_wakeup_event_processed = FALSE;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002277 tNFC_DEACTIVATE_DEVT deact;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002278
2279 switch (event)
2280 {
2281 case NFA_DM_RF_DEACTIVATE_CMD:
Jizhou Liao5cbce032015-06-17 13:57:43 -07002282 if (nfa_dm_cb.disc_cb.activated_protocol == NCI_PROTOCOL_MIFARE)
2283 {
2284 nfa_dm_cb.disc_cb.deact_pending = TRUE;
2285 nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
2286 status = nfa_dm_send_deactivate_cmd (p_data->deactivate_type);
2287 break;
2288 }
2289
Evan Chuc95c79c2013-04-12 17:38:09 -04002290 if (old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002291 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002292 /* sleep wakeup is already enabled when deactivate cmd is requested,
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002293 * keep the information in control block to issue it later */
Evan Chu7c69b272013-05-14 12:48:36 -04002294 nfa_dm_cb.disc_cb.deact_pending = TRUE;
2295 nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002296 }
2297 else
2298 {
2299 status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2300 }
2301
2302 break;
2303 case NFA_DM_RF_DEACTIVATE_RSP:
2304 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
2305 /* register callback to get interface error NTF */
2306 NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002307
2308 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
2309 {
2310 /* it's race condition. received deactivate NTF before receiving RSP */
2311
2312 deact.status = NFC_STATUS_OK;
2313 deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2314 deact.is_ntf = TRUE;
2315 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, (tNFC_DISCOVER*)&deact);
2316
2317 /* NFCC is in IDLE state */
2318 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2319 nfa_dm_start_rf_discover ();
2320 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002321 break;
2322 case NFA_DM_RF_DEACTIVATE_NTF:
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002323 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002324
2325 nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2326
2327 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
2328 {
2329 /* it's race condition. received deactivate NTF before receiving RSP */
2330 /* notify deactivation after receiving deactivate RSP */
2331 NFA_TRACE_DEBUG0 ("Rx deactivate NTF while waiting for deactivate RSP");
2332 break;
2333 }
2334
Evan Chuc95c79c2013-04-12 17:38:09 -04002335 sleep_wakeup_event = TRUE;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002336
2337 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2338
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002339 if ( (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
2340 ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF) )
2341 {
2342 nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
Evan Chuc95c79c2013-04-12 17:38:09 -04002343 if (old_sleep_wakeup_flag)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002344 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002345 sleep_wakeup_event_processed = TRUE;
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002346 /* process pending deactivate request */
Evan Chu7c69b272013-05-14 12:48:36 -04002347 if (nfa_dm_cb.disc_cb.deact_pending)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002348 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002349 /* notify RW module that sleep wakeup is finished */
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002350 /* if deactivation is pending then deactivate */
Evan Chuc95c79c2013-04-12 17:38:09 -04002351 nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_OK);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002352
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002353 /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will not call this function */
2354 nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, TRUE);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002355 }
2356 else
2357 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002358 /* Successfully went to sleep mode for sleep wakeup */
2359 /* Now wake up the tag to complete the operation */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002360 NFC_DiscoverySelect (nfa_dm_cb.disc_cb.activated_rf_disc_id,
2361 nfa_dm_cb.disc_cb.activated_protocol,
2362 nfa_dm_cb.disc_cb.activated_rf_interface);
2363 }
2364
2365 }
2366 }
2367 else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
2368 {
2369 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2370 nfa_dm_start_rf_discover ();
2371 }
2372 else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
2373 {
2374 nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
2375 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
2376 {
2377 /* stop discovery */
2378 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2379 }
2380 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002381 break;
2382
2383 case NFA_DM_CORE_INTF_ERROR_NTF:
Evan Chuc95c79c2013-04-12 17:38:09 -04002384 sleep_wakeup_event = TRUE;
Evan Chudf5080d2013-06-14 13:57:47 -04002385 if ( (!old_sleep_wakeup_flag)
2386 ||(!nfa_dm_cb.disc_cb.deact_pending) )
2387 {
Evan Chu1ba9dcc2013-09-10 10:54:20 +02002388 nfa_dm_send_deactivate_cmd (NFA_DEACTIVATE_TYPE_DISCOVERY);
Evan Chudf5080d2013-06-14 13:57:47 -04002389 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002390 break;
2391
2392 default:
2393 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
2394 break;
2395 }
2396
Evan Chuc95c79c2013-04-12 17:38:09 -04002397 if (old_sleep_wakeup_flag && sleep_wakeup_event && !sleep_wakeup_event_processed)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002398 {
Evan Chuc95c79c2013-04-12 17:38:09 -04002399 /* performing sleep wakeup and exception conditions happened
2400 * clear sleep wakeup information and report failure */
2401 nfa_dm_disc_end_sleep_wakeup (NFC_STATUS_FAILED);
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002402 }
2403}
2404
2405/*******************************************************************************
2406**
2407** Function nfa_dm_disc_sm_listen_active
2408**
2409** Description Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE state
2410**
2411** Returns void
2412**
2413*******************************************************************************/
2414static void nfa_dm_disc_sm_listen_active (tNFA_DM_RF_DISC_SM_EVENT event,
2415 tNFA_DM_RF_DISC_DATA *p_data)
2416{
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002417 tNFC_DEACTIVATE_DEVT deact;
2418
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002419 switch (event)
2420 {
2421 case NFA_DM_RF_DEACTIVATE_CMD:
2422 nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
2423 break;
2424 case NFA_DM_RF_DEACTIVATE_RSP:
2425 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002426 if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002427 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002428 /* it's race condition. received deactivate NTF before receiving RSP */
2429
2430 deact.status = NFC_STATUS_OK;
2431 deact.type = NFC_DEACTIVATE_TYPE_IDLE;
2432 deact.is_ntf = TRUE;
2433 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, (tNFC_DISCOVER*)&deact);
2434
2435 /* NFCC is in IDLE state */
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002436 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2437 nfa_dm_start_rf_discover ();
2438 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002439 break;
2440 case NFA_DM_RF_DEACTIVATE_NTF:
2441 nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
2442
2443 nfa_sys_stop_timer (&nfa_dm_cb.disc_cb.tle);
2444
2445 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002446 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002447 /* it's race condition. received deactivate NTF before receiving RSP */
2448 /* notify deactivation after receiving deactivate RSP */
2449 NFA_TRACE_DEBUG0 ("Rx deactivate NTF while waiting for deactivate RSP");
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002450 }
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002451 else
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002452 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002453 nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
2454
2455 if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002456 {
Martijn Coenen5c65c3a2013-03-27 13:23:36 -07002457 nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
2458 nfa_dm_start_rf_discover ();
2459 }
2460 else if ( (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
2461 ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF) )
2462 {
2463 nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_SLEEP);
2464 }
2465 else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
2466 {
2467 /* Discovery */
2468 nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
2469 if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
2470 {
2471 /* stop discovery */
2472 NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
2473 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002474 }
2475 }
The Android Open Source Projecte9df6ba2012-12-13 14:55:37 -08002476 break;
2477
2478 case NFA_DM_CORE_INTF_ERROR_NTF:
2479 break;
2480 default:
2481 NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
2482 break;
2483 }
2484}
2485
2486/*******************************************************************************
2487**
2488** Function nfa_dm_disc_sm_listen_sleep
2489**
2490** Description Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP state
2491**
2492** Returns void
2493**