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