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