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