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