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