1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This is the main implementation file for the NFA P2P. 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "llcp_api.h" 26 #include "llcp_defs.h" 27 #include "nfa_dm_int.h" 28 #include "nfa_p2p_api.h" 29 #include "nfa_p2p_int.h" 30 #include "nfa_sys.h" 31 #include "nfa_sys_int.h" 32 #include "nfc_api.h" 33 34 /***************************************************************************** 35 ** Global Variables 36 *****************************************************************************/ 37 38 /* system manager control block definition */ 39 tNFA_P2P_CB nfa_p2p_cb; 40 41 /***************************************************************************** 42 ** Static Functions 43 *****************************************************************************/ 44 45 /* event handler function type */ 46 static bool nfa_p2p_evt_hdlr(NFC_HDR* p_msg); 47 48 /* disable function type */ 49 static void nfa_p2p_sys_disable(void); 50 static void nfa_p2p_update_active_listen(void); 51 52 /* debug functions type */ 53 #if (BT_TRACE_VERBOSE == TRUE) 54 static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code); 55 #endif 56 57 /***************************************************************************** 58 ** Constants 59 *****************************************************************************/ 60 /* timeout to restore active listen mode if no RF activation on passive mode */ 61 #define NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT 5000 62 63 static const tNFA_SYS_REG nfa_p2p_sys_reg = {NULL, nfa_p2p_evt_hdlr, 64 nfa_p2p_sys_disable, NULL}; 65 66 #define NFA_P2P_NUM_ACTIONS (NFA_P2P_LAST_EVT & 0x00ff) 67 68 /* type for action functions */ 69 typedef bool (*tNFA_P2P_ACTION)(tNFA_P2P_MSG* p_data); 70 71 /* action function list */ 72 const tNFA_P2P_ACTION nfa_p2p_action[] = { 73 nfa_p2p_reg_server, /* NFA_P2P_API_REG_SERVER_EVT */ 74 nfa_p2p_reg_client, /* NFA_P2P_API_REG_CLIENT_EVT */ 75 nfa_p2p_dereg, /* NFA_P2P_API_DEREG_EVT */ 76 nfa_p2p_accept_connection, /* NFA_P2P_API_ACCEPT_CONN_EVT */ 77 nfa_p2p_reject_connection, /* NFA_P2P_API_REJECT_CONN_EVT */ 78 nfa_p2p_disconnect, /* NFA_P2P_API_DISCONNECT_EVT */ 79 nfa_p2p_create_data_link_connection, /* NFA_P2P_API_CONNECT_EVT */ 80 nfa_p2p_send_ui, /* NFA_P2P_API_SEND_UI_EVT */ 81 nfa_p2p_send_data, /* NFA_P2P_API_SEND_DATA_EVT */ 82 nfa_p2p_set_local_busy, /* NFA_P2P_API_SET_LOCAL_BUSY_EVT */ 83 nfa_p2p_get_link_info, /* NFA_P2P_API_GET_LINK_INFO_EVT */ 84 nfa_p2p_get_remote_sap, /* NFA_P2P_API_GET_REMOTE_SAP_EVT */ 85 nfa_p2p_set_llcp_cfg, /* NFA_P2P_API_SET_LLCP_CFG_EVT */ 86 nfa_p2p_restart_rf_discovery /* NFA_P2P_INT_RESTART_RF_DISC_EVT */ 87 }; 88 89 /******************************************************************************* 90 ** 91 ** Function nfa_p2p_discovery_cback 92 ** 93 ** Description Processing event from discovery callback for listening 94 ** 95 ** 96 ** Returns None 97 ** 98 *******************************************************************************/ 99 void nfa_p2p_discovery_cback(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data) { 100 tNFA_CONN_EVT_DATA evt_data; 101 102 P2P_TRACE_DEBUG1("nfa_p2p_discovery_cback (): event:0x%02X", event); 103 104 switch (event) { 105 case NFA_DM_RF_DISC_START_EVT: 106 if (p_data->status == NFC_STATUS_OK) { 107 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_LISTENING; 108 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY; 109 } 110 break; 111 112 case NFA_DM_RF_DISC_ACTIVATED_EVT: 113 114 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_ACTIVE; 115 116 /* notify NFC link activation */ 117 memcpy(&(evt_data.activated.activate_ntf), &(p_data->activate), 118 sizeof(tNFC_ACTIVATE_DEVT)); 119 nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data); 120 121 if ((p_data->activate.protocol == NFC_PROTOCOL_NFC_DEP) && 122 (p_data->activate.intf_param.type == NFC_INTERFACE_NFC_DEP)) { 123 nfa_p2p_activate_llcp(p_data); 124 125 /* stop timer not to deactivate LLCP link on passive mode */ 126 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 127 } 128 break; 129 130 case NFA_DM_RF_DISC_DEACTIVATED_EVT: 131 132 if ((nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_ACTIVE) && 133 (nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_SLEEP)) { 134 /* this is not for P2P listen 135 ** DM broadcasts deactivaiton event in listen sleep state. 136 */ 137 break; 138 } 139 140 /* notify deactivation */ 141 if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) || 142 (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) { 143 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_SLEEP; 144 evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP; 145 } else { 146 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY; 147 evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE; 148 } 149 nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data); 150 break; 151 152 default: 153 P2P_TRACE_ERROR0("Unexpected event"); 154 break; 155 } 156 } 157 158 /******************************************************************************* 159 ** 160 ** Function nfa_p2p_update_active_listen_timeout_cback 161 ** 162 ** Description Timeout while waiting for passive mode activation 163 ** 164 ** Returns void 165 ** 166 *******************************************************************************/ 167 static void nfa_p2p_update_active_listen_timeout_cback(TIMER_LIST_ENT* p_tle) { 168 NFA_TRACE_ERROR0("nfa_p2p_update_active_listen_timeout_cback()"); 169 170 /* restore active listen mode */ 171 nfa_p2p_update_active_listen(); 172 } 173 174 /******************************************************************************* 175 ** 176 ** Function nfa_p2p_update_active_listen 177 ** 178 ** Description Remove active listen mode temporarily or restore it 179 ** 180 ** 181 ** Returns None 182 ** 183 *******************************************************************************/ 184 static void nfa_p2p_update_active_listen(void) { 185 tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0; 186 NFC_HDR* p_msg; 187 188 P2P_TRACE_DEBUG1( 189 "nfa_p2p_update_active_listen (): listen_tech_mask_to_restore:0x%x", 190 nfa_p2p_cb.listen_tech_mask_to_restore); 191 192 /* if active listen mode was removed temporarily */ 193 if (nfa_p2p_cb.listen_tech_mask_to_restore) { 194 /* restore listen technologies */ 195 nfa_p2p_cb.listen_tech_mask = nfa_p2p_cb.listen_tech_mask_to_restore; 196 nfa_p2p_cb.listen_tech_mask_to_restore = 0; 197 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 198 } else { 199 /* start timer in case of no passive activation */ 200 nfa_p2p_cb.active_listen_restore_timer.p_cback = 201 (TIMER_CBACK*)nfa_p2p_update_active_listen_timeout_cback; 202 nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0, 203 NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT); 204 205 /* save listen techonologies */ 206 nfa_p2p_cb.listen_tech_mask_to_restore = nfa_p2p_cb.listen_tech_mask; 207 208 /* remove active listen mode */ 209 nfa_p2p_cb.listen_tech_mask &= 210 ~(NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE); 211 } 212 213 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 214 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 215 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 216 } 217 218 /* collect listen technologies with NFC-DEP protocol */ 219 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A) 220 p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP; 221 222 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F) 223 p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP; 224 225 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) 226 p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP; 227 228 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) 229 p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP; 230 231 /* Configure listen technologies and protocols and register callback to NFA DM 232 * discovery */ 233 nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover( 234 p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback); 235 236 /* restart RF discovery to update RF technologies */ 237 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR)); 238 if (p_msg != NULL) { 239 p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT; 240 nfa_sys_sendmsg(p_msg); 241 } 242 } 243 244 /******************************************************************************* 245 ** 246 ** Function nfa_p2p_llcp_link_cback 247 ** 248 ** Description Processing event from LLCP link management callback 249 ** 250 ** 251 ** Returns None 252 ** 253 *******************************************************************************/ 254 void nfa_p2p_llcp_link_cback(uint8_t event, uint8_t reason) { 255 tNFA_LLCP_ACTIVATED llcp_activated; 256 tNFA_LLCP_DEACTIVATED llcp_deactivated; 257 258 P2P_TRACE_DEBUG2("nfa_p2p_llcp_link_cback () event:0x%x, reason:0x%x", event, 259 reason); 260 261 if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT) { 262 LLCP_GetLinkMIU(&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu); 263 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED; 264 265 if (nfa_p2p_cb.is_initiator) { 266 /* notify NFA DM to send Activate Event to applicaiton with status */ 267 nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL); 268 } 269 270 llcp_activated.is_initiator = nfa_p2p_cb.is_initiator; 271 llcp_activated.local_link_miu = nfa_p2p_cb.local_link_miu; 272 llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu; 273 llcp_activated.remote_lsc = LLCP_GetRemoteLSC(); 274 llcp_activated.remote_wks = LLCP_GetRemoteWKS(); 275 llcp_activated.remote_version = LLCP_GetRemoteVersion(); 276 277 nfa_dm_act_conn_cback_notify(NFA_LLCP_ACTIVATED_EVT, 278 (tNFA_CONN_EVT_DATA*)&llcp_activated); 279 280 } else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT) { 281 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 282 283 if (nfa_p2p_cb.is_initiator) { 284 /* notify NFA DM to send Activate Event to applicaiton with status */ 285 nfa_dm_notify_activation_status(NFA_STATUS_FAILED, NULL); 286 } 287 288 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 289 } else if (event == LLCP_LINK_FIRST_PACKET_RECEIVED_EVT) { 290 nfa_dm_act_conn_cback_notify(NFA_LLCP_FIRST_PACKET_RECEIVED_EVT, NULL); 291 } else /* LLCP_LINK_DEACTIVATED_EVT */ 292 { 293 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 294 295 /* if got RF link loss without any rx LLC PDU */ 296 if (reason == LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC) { 297 /* if it was active listen mode */ 298 if ((nfa_p2p_cb.is_active_mode) && (!nfa_p2p_cb.is_initiator)) { 299 /* if it didn't retry without active listen mode and passive mode is 300 * available */ 301 if ((nfa_p2p_cb.listen_tech_mask_to_restore == 0x00) && 302 (nfa_p2p_cb.listen_tech_mask & 303 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F))) { 304 P2P_TRACE_DEBUG0("Retry without active listen mode"); 305 306 /* retry without active listen mode */ 307 nfa_p2p_update_active_listen(); 308 } 309 } else if (nfa_p2p_cb.listen_tech_mask_to_restore) { 310 nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0, 311 NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT); 312 } 313 314 reason = LLCP_LINK_RF_LINK_LOSS_ERR; 315 } else { 316 if (nfa_p2p_cb.listen_tech_mask_to_restore) { 317 /* restore active listen mode */ 318 nfa_p2p_update_active_listen(); 319 } 320 } 321 322 llcp_deactivated.reason = reason; 323 nfa_dm_act_conn_cback_notify(NFA_LLCP_DEACTIVATED_EVT, 324 (tNFA_CONN_EVT_DATA*)&llcp_deactivated); 325 326 if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */ 327 { 328 if (nfa_p2p_cb.is_initiator) { 329 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 330 } else if ((nfa_p2p_cb.is_active_mode) && (reason == LLCP_LINK_TIMEOUT)) { 331 /* 332 ** target needs to trun off RF in case of receiving invalid 333 ** frame from initiator 334 */ 335 P2P_TRACE_DEBUG0("Got LLCP_LINK_TIMEOUT in active mode on target"); 336 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 337 } 338 } 339 } 340 } 341 342 /******************************************************************************* 343 ** 344 ** Function nfa_p2p_activate_llcp 345 ** 346 ** Description Activate LLCP link 347 ** 348 ** 349 ** Returns None 350 ** 351 *******************************************************************************/ 352 void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data) { 353 tLLCP_ACTIVATE_CONFIG config; 354 355 P2P_TRACE_DEBUG0("nfa_p2p_activate_llcp ()"); 356 357 if ((p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) || 358 (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) || 359 (p_data->activate.rf_tech_param.mode == 360 NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 361 (p_data->activate.rf_tech_param.mode == 362 NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) { 363 config.is_initiator = true; 364 } else { 365 config.is_initiator = false; 366 } 367 368 if ((p_data->activate.rf_tech_param.mode == 369 NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 370 (p_data->activate.rf_tech_param.mode == 371 NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) || 372 (p_data->activate.rf_tech_param.mode == 373 NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) || 374 (p_data->activate.rf_tech_param.mode == 375 NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) { 376 nfa_p2p_cb.is_active_mode = true; 377 } else { 378 nfa_p2p_cb.is_active_mode = false; 379 } 380 381 nfa_p2p_cb.is_initiator = config.is_initiator; 382 383 config.max_payload_size = 384 p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size; 385 config.waiting_time = 386 p_data->activate.intf_param.intf_param.pa_nfc.waiting_time; 387 config.p_gen_bytes = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes; 388 config.gen_bytes_len = 389 p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len; 390 391 LLCP_ActivateLink(config, nfa_p2p_llcp_link_cback); 392 } 393 394 /******************************************************************************* 395 ** 396 ** Function nfa_p2p_deactivate_llcp 397 ** 398 ** Description Deactivate LLCP link 399 ** 400 ** 401 ** Returns None 402 ** 403 *******************************************************************************/ 404 void nfa_p2p_deactivate_llcp(void) { 405 P2P_TRACE_DEBUG0("nfa_p2p_deactivate_llcp ()"); 406 407 LLCP_DeactivateLink(); 408 } 409 410 /******************************************************************************* 411 ** 412 ** Function nfa_p2p_init 413 ** 414 ** Description Initialize NFA P2P 415 ** 416 ** 417 ** Returns None 418 ** 419 *******************************************************************************/ 420 void nfa_p2p_init(void) { 421 uint8_t xx; 422 423 P2P_TRACE_DEBUG0("nfa_p2p_init ()"); 424 425 /* initialize control block */ 426 memset(&nfa_p2p_cb, 0, sizeof(tNFA_P2P_CB)); 427 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 428 nfa_p2p_cb.trace_level = APPL_INITIAL_TRACE_LEVEL; 429 430 for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) { 431 nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP; 432 } 433 434 /* register message handler on NFA SYS */ 435 nfa_sys_register(NFA_ID_P2P, &nfa_p2p_sys_reg); 436 } 437 438 /******************************************************************************* 439 ** 440 ** Function nfa_p2p_sys_disable 441 ** 442 ** Description Deregister NFA P2P from NFA SYS/DM 443 ** 444 ** 445 ** Returns None 446 ** 447 *******************************************************************************/ 448 static void nfa_p2p_sys_disable(void) { 449 P2P_TRACE_DEBUG0("nfa_p2p_sys_disable()"); 450 451 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 452 453 /* deregister message handler on NFA SYS */ 454 nfa_sys_deregister(NFA_ID_P2P); 455 } 456 457 /******************************************************************************* 458 ** 459 ** Function nfa_p2p_set_config 460 ** 461 ** Description Set General bytes and WT parameters for LLCP 462 ** 463 ** 464 ** Returns void 465 ** 466 *******************************************************************************/ 467 void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask) { 468 uint8_t wt, gen_bytes_len = LLCP_MAX_GEN_BYTES; 469 uint8_t params[LLCP_MAX_GEN_BYTES + 5], *p, length; 470 471 P2P_TRACE_DEBUG0("nfa_p2p_set_config ()"); 472 473 LLCP_GetDiscoveryConfig(&wt, params + 2, &gen_bytes_len); 474 if (nfa_dm_is_p2p_paused()) { 475 gen_bytes_len = 0; 476 } 477 478 if (disc_mask & 479 (NFA_DM_DISC_MASK_PA_NFC_DEP | NFA_DM_DISC_MASK_PF_NFC_DEP | 480 NFA_DM_DISC_MASK_PAA_NFC_DEP | NFA_DM_DISC_MASK_PFA_NFC_DEP)) { 481 p = params; 482 483 UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_REQ_GEN_BYTES); 484 UINT8_TO_BE_STREAM(p, gen_bytes_len); 485 486 p += gen_bytes_len; 487 length = gen_bytes_len + 2; 488 489 nfa_dm_check_set_config(length, params, false); 490 } 491 492 if (disc_mask & 493 (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP | 494 NFA_DM_DISC_MASK_LAA_NFC_DEP | NFA_DM_DISC_MASK_LFA_NFC_DEP)) { 495 p = params; 496 497 UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES); 498 UINT8_TO_BE_STREAM(p, gen_bytes_len); 499 500 p += gen_bytes_len; 501 length = gen_bytes_len + 2; 502 503 UINT8_TO_BE_STREAM(p, NFC_PMID_WT); 504 UINT8_TO_BE_STREAM(p, NCI_PARAM_LEN_WT); 505 UINT8_TO_BE_STREAM(p, wt); 506 507 length += 3; 508 509 nfa_dm_check_set_config(length, params, false); 510 } 511 } 512 513 /******************************************************************************* 514 ** 515 ** Function nfa_p2p_enable_listening 516 ** 517 ** Description Configure listen technologies and protocols for LLCP 518 ** If LLCP WKS is changed then LLCP Gen bytes will be updated. 519 ** 520 ** Returns void 521 ** 522 *******************************************************************************/ 523 void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks) { 524 tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0; 525 526 P2P_TRACE_DEBUG2("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d", 527 sys_id, update_wks); 528 529 if (sys_id == NFA_ID_P2P) 530 nfa_p2p_cb.is_p2p_listening = true; 531 else if (sys_id == NFA_ID_SNEP) 532 nfa_p2p_cb.is_snep_listening = true; 533 534 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 535 /* if need to update WKS in LLCP Gen bytes */ 536 if (update_wks) { 537 /* update LLCP Gen Bytes */ 538 nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP | 539 NFA_DM_DISC_MASK_LA_NFC_DEP); 540 } 541 return; 542 } 543 544 /* collect listen technologies with NFC-DEP protocol */ 545 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A) 546 p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP; 547 548 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F) 549 p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP; 550 551 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) 552 p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP; 553 554 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) 555 p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP; 556 557 if (p2p_listen_mask) { 558 /* Configure listen technologies and protocols and register callback to NFA 559 * DM discovery */ 560 nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover( 561 p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback); 562 } 563 } 564 565 /******************************************************************************* 566 ** 567 ** Function nfa_p2p_disable_listening 568 ** 569 ** Description Remove listen technologies and protocols for LLCP and 570 ** deregister callback from NFA DM discovery if all of 571 ** P2P/CHO/SNEP doesn't listen LLCP any more. 572 ** If LLCP WKS is changed then ATR_RES will be updated. 573 ** 574 ** Returns void 575 ** 576 *******************************************************************************/ 577 void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks) { 578 P2P_TRACE_DEBUG2("nfa_p2p_disable_listening () sys_id = %d, update_wks = %d", 579 sys_id, update_wks); 580 581 if (sys_id == NFA_ID_P2P) 582 nfa_p2p_cb.is_p2p_listening = false; 583 else if (sys_id == NFA_ID_SNEP) 584 nfa_p2p_cb.is_snep_listening = false; 585 586 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 587 if ((nfa_p2p_cb.is_p2p_listening == false) && 588 (nfa_p2p_cb.is_snep_listening == false)) { 589 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 590 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE; 591 592 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 593 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 594 } else if (update_wks) { 595 /* update LLCP Gen Bytes */ 596 nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP | 597 NFA_DM_DISC_MASK_LA_NFC_DEP); 598 } 599 } 600 } 601 602 /******************************************************************************* 603 ** 604 ** Function nfa_p2p_update_listen_tech 605 ** 606 ** Description Update P2P listen technologies. If there is change then 607 ** restart or stop P2P listen. 608 ** 609 ** Returns void 610 ** 611 *******************************************************************************/ 612 void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask) { 613 P2P_TRACE_DEBUG1("nfa_p2p_update_listen_tech () tech_mask = 0x%x", 614 tech_mask); 615 616 if (nfa_p2p_cb.listen_tech_mask_to_restore) { 617 nfa_p2p_cb.listen_tech_mask_to_restore = 0; 618 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 619 } 620 621 if (nfa_p2p_cb.listen_tech_mask != tech_mask) { 622 nfa_p2p_cb.listen_tech_mask = tech_mask; 623 624 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 625 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE; 626 627 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 628 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 629 } 630 631 /* restart discovery without updating sub-module status */ 632 if (nfa_p2p_cb.is_p2p_listening) 633 nfa_p2p_enable_listening(NFA_ID_P2P, false); 634 else if (nfa_p2p_cb.is_snep_listening) 635 nfa_p2p_enable_listening(NFA_ID_SNEP, false); 636 } 637 } 638 639 /******************************************************************************* 640 ** 641 ** Function nfa_p2p_evt_hdlr 642 ** 643 ** Description Processing event for NFA P2P 644 ** 645 ** 646 ** Returns TRUE if p_msg needs to be deallocated 647 ** 648 *******************************************************************************/ 649 static bool nfa_p2p_evt_hdlr(NFC_HDR* p_hdr) { 650 bool delete_msg = true; 651 uint16_t event; 652 653 tNFA_P2P_MSG* p_msg = (tNFA_P2P_MSG*)p_hdr; 654 655 #if (BT_TRACE_VERBOSE == TRUE) 656 P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]", 657 nfa_p2p_llcp_state_code(nfa_p2p_cb.llcp_state), 658 nfa_p2p_evt_code(p_msg->hdr.event)); 659 #else 660 P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x", 661 nfa_p2p_cb.llcp_state, p_msg->hdr.event); 662 #endif 663 664 event = p_msg->hdr.event & 0x00ff; 665 666 /* execute action functions */ 667 if (event < NFA_P2P_NUM_ACTIONS) { 668 delete_msg = (*nfa_p2p_action[event])(p_msg); 669 } else { 670 P2P_TRACE_ERROR0("Unhandled event"); 671 } 672 673 return delete_msg; 674 } 675 676 #if (BT_TRACE_VERBOSE == TRUE) 677 /******************************************************************************* 678 ** 679 ** Function nfa_p2p_llcp_state_code 680 ** 681 ** Description 682 ** 683 ** Returns string of state 684 ** 685 *******************************************************************************/ 686 static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code) { 687 switch (state_code) { 688 case NFA_P2P_LLCP_STATE_IDLE: 689 return "Link IDLE"; 690 case NFA_P2P_LLCP_STATE_LISTENING: 691 return "Link LISTENING"; 692 case NFA_P2P_LLCP_STATE_ACTIVATED: 693 return "Link ACTIVATED"; 694 default: 695 return "Unknown state"; 696 } 697 } 698 699 /******************************************************************************* 700 ** 701 ** Function nfa_p2p_evt_code 702 ** 703 ** Description 704 ** 705 ** Returns string of event 706 ** 707 *******************************************************************************/ 708 char* nfa_p2p_evt_code(uint16_t evt_code) { 709 switch (evt_code) { 710 case NFA_P2P_API_REG_SERVER_EVT: 711 return "API_REG_SERVER"; 712 case NFA_P2P_API_REG_CLIENT_EVT: 713 return "API_REG_CLIENT"; 714 case NFA_P2P_API_DEREG_EVT: 715 return "API_DEREG"; 716 case NFA_P2P_API_ACCEPT_CONN_EVT: 717 return "API_ACCEPT_CONN"; 718 case NFA_P2P_API_REJECT_CONN_EVT: 719 return "API_REJECT_CONN"; 720 case NFA_P2P_API_DISCONNECT_EVT: 721 return "API_DISCONNECT"; 722 case NFA_P2P_API_CONNECT_EVT: 723 return "API_CONNECT"; 724 case NFA_P2P_API_SEND_UI_EVT: 725 return "API_SEND_UI"; 726 case NFA_P2P_API_SEND_DATA_EVT: 727 return "API_SEND_DATA"; 728 case NFA_P2P_API_SET_LOCAL_BUSY_EVT: 729 return "API_SET_LOCAL_BUSY"; 730 case NFA_P2P_API_GET_LINK_INFO_EVT: 731 return "API_GET_LINK_INFO"; 732 case NFA_P2P_API_GET_REMOTE_SAP_EVT: 733 return "API_GET_REMOTE_SAP"; 734 case NFA_P2P_API_SET_LLCP_CFG_EVT: 735 return "API_SET_LLCP_CFG_EVT"; 736 case NFA_P2P_INT_RESTART_RF_DISC_EVT: 737 return "RESTART_RF_DISC_EVT"; 738 default: 739 return "Unknown event"; 740 } 741 } 742 #endif /* Debug Functions */ 743