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