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