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