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 */ 39tNFA_P2P_CB nfa_p2p_cb; 40 41/***************************************************************************** 42** Static Functions 43*****************************************************************************/ 44 45/* event handler function type */ 46static bool nfa_p2p_evt_hdlr(NFC_HDR* p_msg); 47 48/* disable function type */ 49static void nfa_p2p_sys_disable(void); 50static void nfa_p2p_update_active_listen(void); 51 52/* debug functions type */ 53#if (BT_TRACE_VERBOSE == TRUE) 54static 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 63static 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 */ 69typedef bool (*tNFA_P2P_ACTION)(tNFA_P2P_MSG* p_data); 70 71/* action function list */ 72const 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*******************************************************************************/ 99void 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*******************************************************************************/ 167static 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*******************************************************************************/ 184static 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 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 210 nfa_p2p_cb.listen_tech_mask &= ~(NFA_TECHNOLOGY_MASK_ACTIVE); 211 } else { 212 nfa_p2p_cb.listen_tech_mask &= 213 ~(NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE); 214 } 215 } 216 217 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 218 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 219 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 220 } 221 222 /* collect listen technologies with NFC-DEP protocol */ 223 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A) 224 p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP; 225 226 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F) 227 p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP; 228 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 229 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE) 230 p2p_listen_mask |= NFA_DM_DISC_MASK_LACM_NFC_DEP; 231 } else { 232 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) 233 p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP; 234 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) 235 p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP; 236 } 237 238 /* For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. For 239 * LLCP DTA mode activate LLCP Bypassing LLCP is handled in 240 * nfa_dm_poll_disc_cback */ 241 242 if (appl_dta_mode_flag == 1 && 243 ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) { 244 // Configure listen technologies and protocols and register callback to DTA 245 246 P2P_TRACE_DEBUG1( 247 "%s: DTA mode:Registering nfa_dm_poll_disc_cback to avoid LLCP in P2P", 248 __func__); 249 nfa_p2p_cb.dm_disc_handle = 250 nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, 251 nfa_dm_poll_disc_cback_dta_wrapper); 252 } else { 253 /* Configure listen technologies and protocols and register callback to NFA 254 * DM discovery */ 255 nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover( 256 p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback); 257 } 258 259 /* restart RF discovery to update RF technologies */ 260 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR)); 261 if (p_msg != NULL) { 262 p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT; 263 nfa_sys_sendmsg(p_msg); 264 } 265} 266 267/******************************************************************************* 268** 269** Function nfa_p2p_llcp_link_cback 270** 271** Description Processing event from LLCP link management callback 272** 273** 274** Returns None 275** 276*******************************************************************************/ 277void nfa_p2p_llcp_link_cback(uint8_t event, uint8_t reason) { 278 tNFA_LLCP_ACTIVATED llcp_activated; 279 tNFA_LLCP_DEACTIVATED llcp_deactivated; 280 281 P2P_TRACE_DEBUG2("nfa_p2p_llcp_link_cback () event:0x%x, reason:0x%x", event, 282 reason); 283 284 if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT) { 285 LLCP_GetLinkMIU(&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu); 286 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED; 287 288 if (nfa_p2p_cb.is_initiator) { 289 /* notify NFA DM to send Activate Event to applicaiton with status */ 290 nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL); 291 } 292 293 llcp_activated.is_initiator = nfa_p2p_cb.is_initiator; 294 llcp_activated.local_link_miu = nfa_p2p_cb.local_link_miu; 295 llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu; 296 llcp_activated.remote_lsc = LLCP_GetRemoteLSC(); 297 llcp_activated.remote_wks = LLCP_GetRemoteWKS(); 298 llcp_activated.remote_version = LLCP_GetRemoteVersion(); 299 300 nfa_dm_act_conn_cback_notify(NFA_LLCP_ACTIVATED_EVT, 301 (tNFA_CONN_EVT_DATA*)&llcp_activated); 302 303 } else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT) { 304 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 305 306 if (nfa_p2p_cb.is_initiator) { 307 /* notify NFA DM to send Activate Event to applicaiton with status */ 308 nfa_dm_notify_activation_status(NFA_STATUS_FAILED, NULL); 309 } 310 311 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 312 } else if (event == LLCP_LINK_FIRST_PACKET_RECEIVED_EVT) { 313 nfa_dm_act_conn_cback_notify(NFA_LLCP_FIRST_PACKET_RECEIVED_EVT, NULL); 314 } else /* LLCP_LINK_DEACTIVATED_EVT */ 315 { 316 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 317 318 /* if got RF link loss without any rx LLC PDU */ 319 if (reason == LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC) { 320 /* if it was active listen mode */ 321 if ((nfa_p2p_cb.is_active_mode) && (!nfa_p2p_cb.is_initiator)) { 322 /* if it didn't retry without active listen mode and passive mode is 323 * available */ 324 if ((nfa_p2p_cb.listen_tech_mask_to_restore == 0x00) && 325 (nfa_p2p_cb.listen_tech_mask & 326 (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F))) { 327 P2P_TRACE_DEBUG0("Retry without active listen mode"); 328 329 /* retry without active listen mode */ 330 nfa_p2p_update_active_listen(); 331 } 332 } else if (nfa_p2p_cb.listen_tech_mask_to_restore) { 333 nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0, 334 NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT); 335 } 336 337 reason = LLCP_LINK_RF_LINK_LOSS_ERR; 338 } else { 339 if (nfa_p2p_cb.listen_tech_mask_to_restore) { 340 /* restore active listen mode */ 341 nfa_p2p_update_active_listen(); 342 } 343 } 344 345 llcp_deactivated.reason = reason; 346 nfa_dm_act_conn_cback_notify(NFA_LLCP_DEACTIVATED_EVT, 347 (tNFA_CONN_EVT_DATA*)&llcp_deactivated); 348 349 if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */ 350 { 351 if (nfa_p2p_cb.is_initiator) { 352 /*For LLCP DTA test, Deactivate to Sleep is needed to send DSL_REQ*/ 353 if (appl_dta_mode_flag == 1 && 354 ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_LLCP_MODE)) { 355 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_SLEEP); 356 } else { 357 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 358 } 359 } else if ((nfa_p2p_cb.is_active_mode) && (reason == LLCP_LINK_TIMEOUT)) { 360 /* 361 ** target needs to trun off RF in case of receiving invalid 362 ** frame from initiator 363 */ 364 P2P_TRACE_DEBUG0("Got LLCP_LINK_TIMEOUT in active mode on target"); 365 nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY); 366 } 367 } 368 } 369} 370 371/******************************************************************************* 372** 373** Function nfa_p2p_activate_llcp 374** 375** Description Activate LLCP link 376** 377** 378** Returns None 379** 380*******************************************************************************/ 381void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data) { 382 tLLCP_ACTIVATE_CONFIG config; 383 384 P2P_TRACE_DEBUG0("nfa_p2p_activate_llcp ()"); 385 386 if ((p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) || 387 (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F)) { 388 config.is_initiator = true; 389 } else { 390 config.is_initiator = false; 391 } 392 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 393 if (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_ACTIVE) { 394 config.is_initiator = true; 395 } 396 } else { 397 if ((p_data->activate.rf_tech_param.mode == 398 NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 399 (p_data->activate.rf_tech_param.mode == 400 NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) { 401 config.is_initiator = true; 402 } 403 } 404 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 405 if ((p_data->activate.rf_tech_param.mode == 406 NFC_DISCOVERY_TYPE_POLL_ACTIVE) || 407 (p_data->activate.rf_tech_param.mode == 408 NFC_DISCOVERY_TYPE_LISTEN_ACTIVE)) { 409 nfa_p2p_cb.is_active_mode = true; 410 } else { 411 nfa_p2p_cb.is_active_mode = false; 412 } 413 } else { 414 if ((p_data->activate.rf_tech_param.mode == 415 NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) || 416 (p_data->activate.rf_tech_param.mode == 417 NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) || 418 (p_data->activate.rf_tech_param.mode == 419 NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) || 420 (p_data->activate.rf_tech_param.mode == 421 NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) { 422 nfa_p2p_cb.is_active_mode = true; 423 } else { 424 nfa_p2p_cb.is_active_mode = false; 425 } 426 } 427 428 nfa_p2p_cb.is_initiator = config.is_initiator; 429 430 config.max_payload_size = 431 p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size; 432 config.waiting_time = 433 p_data->activate.intf_param.intf_param.pa_nfc.waiting_time; 434 config.p_gen_bytes = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes; 435 config.gen_bytes_len = 436 p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len; 437 438 LLCP_ActivateLink(config, nfa_p2p_llcp_link_cback); 439} 440 441/******************************************************************************* 442** 443** Function nfa_p2p_deactivate_llcp 444** 445** Description Deactivate LLCP link 446** 447** 448** Returns None 449** 450*******************************************************************************/ 451void nfa_p2p_deactivate_llcp(void) { 452 P2P_TRACE_DEBUG0("nfa_p2p_deactivate_llcp ()"); 453 454 LLCP_DeactivateLink(); 455} 456 457/******************************************************************************* 458** 459** Function nfa_p2p_init 460** 461** Description Initialize NFA P2P 462** 463** 464** Returns None 465** 466*******************************************************************************/ 467void nfa_p2p_init(void) { 468 uint8_t xx; 469 470 P2P_TRACE_DEBUG0("nfa_p2p_init ()"); 471 472 /* initialize control block */ 473 memset(&nfa_p2p_cb, 0, sizeof(tNFA_P2P_CB)); 474 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 475 nfa_p2p_cb.trace_level = APPL_INITIAL_TRACE_LEVEL; 476 477 for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) { 478 nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP; 479 } 480 481 /* register message handler on NFA SYS */ 482 nfa_sys_register(NFA_ID_P2P, &nfa_p2p_sys_reg); 483} 484 485/******************************************************************************* 486** 487** Function nfa_p2p_sys_disable 488** 489** Description Deregister NFA P2P from NFA SYS/DM 490** 491** 492** Returns None 493** 494*******************************************************************************/ 495static void nfa_p2p_sys_disable(void) { 496 P2P_TRACE_DEBUG0("nfa_p2p_sys_disable()"); 497 498 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 499 500 /* deregister message handler on NFA SYS */ 501 nfa_sys_deregister(NFA_ID_P2P); 502} 503 504/******************************************************************************* 505** 506** Function nfa_p2p_set_config 507** 508** Description Set General bytes and WT parameters for LLCP 509** 510** 511** Returns void 512** 513*******************************************************************************/ 514void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask) { 515 uint8_t wt, gen_bytes_len = LLCP_MAX_GEN_BYTES; 516 uint8_t params[LLCP_MAX_GEN_BYTES + 5], *p, length; 517 518 P2P_TRACE_DEBUG0("nfa_p2p_set_config ()"); 519 520 LLCP_GetDiscoveryConfig(&wt, params + 2, &gen_bytes_len); 521 if (nfa_dm_is_p2p_paused()) { 522 gen_bytes_len = 0; 523 } 524 525 if ((disc_mask & 526 (NFA_DM_DISC_MASK_PA_NFC_DEP | NFA_DM_DISC_MASK_PF_NFC_DEP)) || 527 ((NFC_GetNCIVersion() == NCI_VERSION_2_0) && 528 (disc_mask & NFA_DM_DISC_MASK_PACM_NFC_DEP)) || 529 ((NFC_GetNCIVersion() != NCI_VERSION_2_0) && 530 (disc_mask & 531 (NFA_DM_DISC_MASK_PAA_NFC_DEP | NFA_DM_DISC_MASK_PFA_NFC_DEP)))) { 532 p = params; 533 534 UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_REQ_GEN_BYTES); 535 UINT8_TO_BE_STREAM(p, gen_bytes_len); 536 537 p += gen_bytes_len; 538 length = gen_bytes_len + 2; 539 540 nfa_dm_check_set_config(length, params, false); 541 } 542 543 if ((disc_mask & 544 (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP)) || 545 ((NFC_GetNCIVersion() == NCI_VERSION_2_0) && 546 (disc_mask & NFA_DM_DISC_MASK_LACM_NFC_DEP)) || 547 ((NFC_GetNCIVersion() != NCI_VERSION_2_0) && 548 (disc_mask & 549 (NFA_DM_DISC_MASK_LFA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP)))) { 550 p = params; 551 552 UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES); 553 UINT8_TO_BE_STREAM(p, gen_bytes_len); 554 555 p += gen_bytes_len; 556 length = gen_bytes_len + 2; 557 558 UINT8_TO_BE_STREAM(p, NFC_PMID_WT); 559 UINT8_TO_BE_STREAM(p, NCI_PARAM_LEN_WT); 560 UINT8_TO_BE_STREAM(p, wt); 561 562 length += 3; 563 564 nfa_dm_check_set_config(length, params, false); 565 } 566} 567 568/******************************************************************************* 569** 570** Function nfa_p2p_enable_listening 571** 572** Description Configure listen technologies and protocols for LLCP 573** If LLCP WKS is changed then LLCP Gen bytes will be updated. 574** 575** Returns void 576** 577*******************************************************************************/ 578void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks) { 579 tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0; 580 581 P2P_TRACE_DEBUG2("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d", 582 sys_id, update_wks); 583 584 if (sys_id == NFA_ID_P2P) 585 nfa_p2p_cb.is_p2p_listening = true; 586 else if (sys_id == NFA_ID_SNEP) 587 nfa_p2p_cb.is_snep_listening = true; 588 589 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 590 /* if need to update WKS in LLCP Gen bytes */ 591 if (update_wks) { 592 /* update LLCP Gen Bytes */ 593 nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP | 594 NFA_DM_DISC_MASK_LA_NFC_DEP); 595 } 596 return; 597 } 598 599 /* collect listen technologies with NFC-DEP protocol */ 600 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A) 601 p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP; 602 603 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F) 604 p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP; 605 606 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 607 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE) 608 p2p_listen_mask |= NFA_DM_DISC_MASK_LACM_NFC_DEP; 609 } else { 610 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) 611 p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP; 612 613 if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) 614 p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP; 615 } 616 617 if (p2p_listen_mask) { 618 /* For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. 619 * For LLCP DTA mode activate LLCP Bypassing LLCP is handled in 620 * nfa_dm_poll_disc_cback */ 621 if (appl_dta_mode_flag == 1 && 622 ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) { 623 /* Configure listen technologies and protocols and register callback to 624 * NFA DM discovery */ 625 P2P_TRACE_DEBUG1( 626 "%s: DTA mode:Registering nfa_dm_poll_disc_cback to avoid LLCP in " 627 "P2P", 628 __func__); 629 nfa_p2p_cb.dm_disc_handle = 630 nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, 631 nfa_dm_poll_disc_cback_dta_wrapper); 632 } else { 633 /* Configure listen technologies and protocols and register callback to 634 * NFA DM discovery */ 635 nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover( 636 p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback); 637 } 638 } 639} 640 641/******************************************************************************* 642** 643** Function nfa_p2p_disable_listening 644** 645** Description Remove listen technologies and protocols for LLCP and 646** deregister callback from NFA DM discovery if all of 647** P2P/CHO/SNEP doesn't listen LLCP any more. 648** If LLCP WKS is changed then ATR_RES will be updated. 649** 650** Returns void 651** 652*******************************************************************************/ 653void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks) { 654 P2P_TRACE_DEBUG2("nfa_p2p_disable_listening () sys_id = %d, update_wks = %d", 655 sys_id, update_wks); 656 657 if (sys_id == NFA_ID_P2P) 658 nfa_p2p_cb.is_p2p_listening = false; 659 else if (sys_id == NFA_ID_SNEP) 660 nfa_p2p_cb.is_snep_listening = false; 661 662 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 663 if ((nfa_p2p_cb.is_p2p_listening == false) && 664 (nfa_p2p_cb.is_snep_listening == false)) { 665 nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE; 666 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE; 667 668 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 669 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 670 } else if (update_wks) { 671 /* update LLCP Gen Bytes */ 672 nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP | 673 NFA_DM_DISC_MASK_LA_NFC_DEP); 674 } 675 } 676} 677 678/******************************************************************************* 679** 680** Function nfa_p2p_update_listen_tech 681** 682** Description Update P2P listen technologies. If there is change then 683** restart or stop P2P listen. 684** 685** Returns void 686** 687*******************************************************************************/ 688void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask) { 689 P2P_TRACE_DEBUG1("nfa_p2p_update_listen_tech () tech_mask = 0x%x", 690 tech_mask); 691 692 if (nfa_p2p_cb.listen_tech_mask_to_restore) { 693 nfa_p2p_cb.listen_tech_mask_to_restore = 0; 694 nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer); 695 } 696 697 if (nfa_p2p_cb.listen_tech_mask != tech_mask) { 698 nfa_p2p_cb.listen_tech_mask = tech_mask; 699 700 if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) { 701 nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE; 702 703 nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle); 704 nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID; 705 } 706 707 /* restart discovery without updating sub-module status */ 708 if (nfa_p2p_cb.is_p2p_listening || appl_dta_mode_flag) 709 nfa_p2p_enable_listening(NFA_ID_P2P, false); 710 else if (nfa_p2p_cb.is_snep_listening) 711 nfa_p2p_enable_listening(NFA_ID_SNEP, false); 712 } 713} 714 715/******************************************************************************* 716** 717** Function nfa_p2p_evt_hdlr 718** 719** Description Processing event for NFA P2P 720** 721** 722** Returns TRUE if p_msg needs to be deallocated 723** 724*******************************************************************************/ 725static bool nfa_p2p_evt_hdlr(NFC_HDR* p_hdr) { 726 bool delete_msg = true; 727 uint16_t event; 728 729 tNFA_P2P_MSG* p_msg = (tNFA_P2P_MSG*)p_hdr; 730 731#if (BT_TRACE_VERBOSE == TRUE) 732 P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]", 733 nfa_p2p_llcp_state_code(nfa_p2p_cb.llcp_state), 734 nfa_p2p_evt_code(p_msg->hdr.event)); 735#else 736 P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x", 737 nfa_p2p_cb.llcp_state, p_msg->hdr.event); 738#endif 739 740 event = p_msg->hdr.event & 0x00ff; 741 742 /* execute action functions */ 743 if (event < NFA_P2P_NUM_ACTIONS) { 744 delete_msg = (*nfa_p2p_action[event])(p_msg); 745 } else { 746 P2P_TRACE_ERROR0("Unhandled event"); 747 } 748 749 return delete_msg; 750} 751 752#if (BT_TRACE_VERBOSE == TRUE) 753/******************************************************************************* 754** 755** Function nfa_p2p_llcp_state_code 756** 757** Description 758** 759** Returns string of state 760** 761*******************************************************************************/ 762static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code) { 763 switch (state_code) { 764 case NFA_P2P_LLCP_STATE_IDLE: 765 return "Link IDLE"; 766 case NFA_P2P_LLCP_STATE_LISTENING: 767 return "Link LISTENING"; 768 case NFA_P2P_LLCP_STATE_ACTIVATED: 769 return "Link ACTIVATED"; 770 default: 771 return "Unknown state"; 772 } 773} 774 775/******************************************************************************* 776** 777** Function nfa_p2p_evt_code 778** 779** Description 780** 781** Returns string of event 782** 783*******************************************************************************/ 784char* nfa_p2p_evt_code(uint16_t evt_code) { 785 switch (evt_code) { 786 case NFA_P2P_API_REG_SERVER_EVT: 787 return "API_REG_SERVER"; 788 case NFA_P2P_API_REG_CLIENT_EVT: 789 return "API_REG_CLIENT"; 790 case NFA_P2P_API_DEREG_EVT: 791 return "API_DEREG"; 792 case NFA_P2P_API_ACCEPT_CONN_EVT: 793 return "API_ACCEPT_CONN"; 794 case NFA_P2P_API_REJECT_CONN_EVT: 795 return "API_REJECT_CONN"; 796 case NFA_P2P_API_DISCONNECT_EVT: 797 return "API_DISCONNECT"; 798 case NFA_P2P_API_CONNECT_EVT: 799 return "API_CONNECT"; 800 case NFA_P2P_API_SEND_UI_EVT: 801 return "API_SEND_UI"; 802 case NFA_P2P_API_SEND_DATA_EVT: 803 return "API_SEND_DATA"; 804 case NFA_P2P_API_SET_LOCAL_BUSY_EVT: 805 return "API_SET_LOCAL_BUSY"; 806 case NFA_P2P_API_GET_LINK_INFO_EVT: 807 return "API_GET_LINK_INFO"; 808 case NFA_P2P_API_GET_REMOTE_SAP_EVT: 809 return "API_GET_REMOTE_SAP"; 810 case NFA_P2P_API_SET_LLCP_CFG_EVT: 811 return "API_SET_LLCP_CFG_EVT"; 812 case NFA_P2P_INT_RESTART_RF_DISC_EVT: 813 return "RESTART_RF_DISC_EVT"; 814 default: 815 return "Unknown event"; 816 } 817} 818#endif /* Debug Functions */ 819