nfa_p2p_act.c revision 63f80ce896f0f8c203191b4e44e038fecb6be02a
1/***************************************************************************** 2** 3** Name: nfa_p2p_act.c 4** 5** Description: This is the implementation file for the NFA P2P. 6** 7** Copyright (c) 2010-2011, Broadcom Corp., All Rights Reserved. 8** Broadcom Bluetooth Core. Proprietary and confidential. 9** 10*****************************************************************************/ 11 12#include "string.h" 13#include "nfc_api.h" 14#include "nfa_sys.h" 15#include "nfa_sys_int.h" 16#include "nfa_dm_int.h" 17#include "llcp_defs.h" 18#include "llcp_api.h" 19#include "nfa_p2p_api.h" 20#include "nfa_p2p_int.h" 21 22/***************************************************************************** 23** Global Variables 24*****************************************************************************/ 25 26/***************************************************************************** 27** Static Functions 28*****************************************************************************/ 29 30/***************************************************************************** 31** Constants 32*****************************************************************************/ 33 34/******************************************************************************* 35** 36** Function nfa_p2p_allocate_conn_cb 37** 38** Description Allocate data link connection control block 39** 40** 41** Returns UINT8 42** 43*******************************************************************************/ 44static UINT8 nfa_p2p_allocate_conn_cb (UINT8 local_sap) 45{ 46 UINT8 xx; 47 48 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) 49 { 50 if (nfa_p2p_cb.conn_cb[xx].flags == 0) 51 { 52 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_IN_USE; 53 nfa_p2p_cb.conn_cb[xx].local_sap = local_sap; 54 55 return (xx); 56 } 57 } 58 59 P2P_TRACE_ERROR0 ("nfa_p2p_allocate_conn_cb (): No resource"); 60 61 return LLCP_MAX_DATA_LINK; 62} 63 64/******************************************************************************* 65** 66** Function nfa_p2p_deallocate_conn_cb 67** 68** Description Deallocate data link connection control block 69** 70** 71** Returns void 72** 73*******************************************************************************/ 74static void nfa_p2p_deallocate_conn_cb (UINT8 xx) 75{ 76 if (xx < LLCP_MAX_DATA_LINK) 77 { 78 nfa_p2p_cb.conn_cb[xx].flags = 0; 79 } 80 else 81 { 82 P2P_TRACE_ERROR1 ("nfa_p2p_deallocate_conn_cb (): Invalid index (%d)", xx); 83 } 84} 85 86/******************************************************************************* 87** 88** Function nfa_p2p_find_conn_cb 89** 90** Description Find data link connection control block by local/remote SAP 91** 92** 93** Returns UINT8 94** 95*******************************************************************************/ 96static UINT8 nfa_p2p_find_conn_cb (UINT8 local_sap, UINT8 remote_sap) 97{ 98 UINT8 xx; 99 100 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) 101 { 102 if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) 103 &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap) 104 &&(nfa_p2p_cb.conn_cb[xx].remote_sap == remote_sap) ) 105 { 106 return (xx); 107 } 108 } 109 110 return (LLCP_MAX_DATA_LINK); 111} 112 113/******************************************************************************* 114** 115** Function nfa_p2p_llcp_cback 116** 117** Description Processing SAP callback events from LLCP 118** 119** 120** Returns None 121** 122*******************************************************************************/ 123static void nfa_p2p_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data) 124{ 125 P2P_TRACE_DEBUG2 ("nfa_p2p_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap); 126 127 switch (p_data->hdr.event) 128 { 129 case LLCP_SAP_EVT_DATA_IND: 130 nfa_p2p_proc_llcp_data_ind (p_data); 131 break; 132 133 case LLCP_SAP_EVT_CONNECT_IND: 134 nfa_p2p_proc_llcp_connect_ind (p_data); 135 break; 136 137 case LLCP_SAP_EVT_CONNECT_RESP: 138 nfa_p2p_proc_llcp_connect_resp (p_data); 139 break; 140 141 case LLCP_SAP_EVT_DISCONNECT_IND: 142 nfa_p2p_proc_llcp_disconnect_ind (p_data); 143 break; 144 145 case LLCP_SAP_EVT_DISCONNECT_RESP: 146 nfa_p2p_proc_llcp_disconnect_resp (p_data); 147 break; 148 149 case LLCP_SAP_EVT_CONGEST: 150 nfa_p2p_proc_llcp_congestion (p_data); 151 break; 152 153 case LLCP_SAP_EVT_LINK_STATUS: 154 nfa_p2p_proc_llcp_link_status (p_data); 155 break; 156 157 default: 158 P2P_TRACE_ERROR1 ("nfa_p2p_llcp_cback (): Unknown event:0x%02X", p_data->hdr.event); 159 return; 160 } 161} 162 163/******************************************************************************* 164** 165** Function nfa_p2p_sdp_cback 166** 167** Description Process SDP callback event from LLCP 168** 169** 170** Returns None 171** 172*******************************************************************************/ 173void nfa_p2p_sdp_cback (UINT8 tid, UINT8 remote_sap) 174{ 175 UINT8 local_sap; 176 UINT8 xx; 177 tNFA_P2P_EVT_DATA evt_data; 178 179 P2P_TRACE_DEBUG2 ("nfa_p2p_sdp_cback (): tid:0x%02X, remote_sap:0x%02X", tid, remote_sap); 180 181 /* search for callback function to process */ 182 for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) 183 { 184 if ( (nfa_p2p_cb.sdp_cb[xx].local_sap != LLCP_INVALID_SAP) 185 &&(nfa_p2p_cb.sdp_cb[xx].tid == tid) ) 186 { 187 local_sap = nfa_p2p_cb.sdp_cb[xx].local_sap; 188 189 evt_data.sdp.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 190 evt_data.sdp.remote_sap = remote_sap; 191 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data); 192 193 nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP; 194 break; 195 } 196 } 197} 198 199/******************************************************************************* 200** 201** Function nfa_p2p_start_sdp 202** 203** Description Initiate SDP 204** 205** 206** Returns TRUE if success 207** 208*******************************************************************************/ 209BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap) 210{ 211 int xx; 212 213 P2P_TRACE_DEBUG1 ("nfa_p2p_start_sdp (): SN:<%s>", p_service_name); 214 215 /* search for empty slot */ 216 for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) 217 { 218 if (nfa_p2p_cb.sdp_cb[xx].local_sap == LLCP_INVALID_SAP) 219 { 220 if (LLCP_DiscoverService (p_service_name, 221 nfa_p2p_sdp_cback, 222 &(nfa_p2p_cb.sdp_cb[xx].tid)) == LLCP_STATUS_SUCCESS) 223 { 224 nfa_p2p_cb.sdp_cb[xx].local_sap = local_sap; 225 return TRUE; 226 } 227 else 228 { 229 /* failure of SDP */ 230 return FALSE; 231 } 232 } 233 } 234 return FALSE; 235} 236 237/******************************************************************************* 238** 239** Function nfa_p2p_proc_llcp_data_ind 240** 241** Description Processing incoming data event from LLCP 242** 243** 244** Returns None 245** 246*******************************************************************************/ 247void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA *p_data) 248{ 249 UINT8 local_sap, xx; 250 tNFA_P2P_EVT_DATA evt_data; 251 252 P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_data_ind ()"); 253 254 local_sap = p_data->data_ind.local_sap; 255 256 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 257 { 258 evt_data.data.handle = 0; 259 /* if connectionless */ 260 if (p_data->data_ind.link_type == NFA_P2P_LLINK_TYPE) 261 { 262 evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 263 } 264 else 265 { 266 xx = nfa_p2p_find_conn_cb (p_data->data_ind.local_sap, 267 p_data->data_ind.remote_sap); 268 269 if (xx != LLCP_MAX_DATA_LINK) 270 { 271 evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 272 } 273 } 274 275 evt_data.data.remote_sap = p_data->data_ind.remote_sap; 276 evt_data.data.link_type = p_data->data_ind.link_type; 277 278 /* notify upper layer that there are data at LLCP */ 279 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DATA_EVT, &evt_data); 280 } 281} 282 283/******************************************************************************* 284** 285** Function nfa_p2p_proc_llcp_connect_ind 286** 287** Description Processing connection request from peer 288** 289** 290** Returns None 291** 292*******************************************************************************/ 293void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA *p_data) 294{ 295 UINT8 server_sap, local_sap; 296 tNFA_P2P_EVT_DATA evt_data; 297 UINT8 xx; 298 299 P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_connect_ind () server_sap:0x%x", 300 p_data->connect_ind.server_sap); 301 302 server_sap = p_data->connect_ind.server_sap; 303 local_sap = p_data->connect_ind.local_sap; 304 305 if (nfa_p2p_cb.sap_cb[server_sap].p_cback) 306 { 307 xx = nfa_p2p_allocate_conn_cb (server_sap); 308 309 if (xx != LLCP_MAX_DATA_LINK) 310 { 311 nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_ind.remote_sap; 312 nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_ind.miu; 313 314 /* peer will not receive any data */ 315 if (p_data->connect_ind.rw == 0) 316 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO; 317 318 evt_data.conn_req.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap); 319 evt_data.conn_req.conn_handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 320 evt_data.conn_req.remote_sap = p_data->connect_ind.remote_sap; 321 evt_data.conn_req.remote_miu = p_data->connect_ind.miu; 322 evt_data.conn_req.remote_rw = p_data->connect_ind.rw; 323 324 nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_CONN_REQ_EVT, &evt_data); 325 } 326 } 327 else 328 { 329 P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_connect_ind (): Not registered"); 330 } 331} 332 333/******************************************************************************* 334** 335** Function nfa_p2p_proc_llcp_connect_resp 336** 337** Description Processing connection response from peer 338** 339** 340** Returns None 341** 342*******************************************************************************/ 343void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA *p_data) 344{ 345 UINT8 local_sap, xx; 346 tNFA_P2P_EVT_DATA evt_data; 347 348 P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_connect_resp ()"); 349 350 local_sap = p_data->connect_resp.local_sap; 351 352 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 353 { 354 xx = nfa_p2p_allocate_conn_cb (local_sap); 355 356 if (xx != LLCP_MAX_DATA_LINK) 357 { 358 nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_resp.remote_sap; 359 nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_resp.miu; 360 361 /* peer will not receive any data */ 362 if (p_data->connect_resp.rw == 0) 363 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO; 364 365 evt_data.connected.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap); 366 evt_data.connected.conn_handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 367 evt_data.connected.remote_sap = p_data->connect_resp.remote_sap; 368 evt_data.connected.remote_miu = p_data->connect_resp.miu; 369 evt_data.connected.remote_rw = p_data->connect_resp.rw; 370 371 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONNECTED_EVT, &evt_data); 372 } 373 } 374} 375 376/******************************************************************************* 377** 378** Function nfa_p2p_proc_llcp_disconnect_ind 379** 380** Description Processing disconnection request from peer 381** 382** 383** Returns None 384** 385*******************************************************************************/ 386void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA *p_data) 387{ 388 UINT8 local_sap, xx; 389 tNFA_P2P_EVT_DATA evt_data; 390 391 P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_ind ()"); 392 393 local_sap = p_data->disconnect_ind.local_sap; 394 395 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 396 { 397 xx = nfa_p2p_find_conn_cb (p_data->disconnect_ind.local_sap, 398 p_data->disconnect_ind.remote_sap); 399 400 if (xx != LLCP_MAX_DATA_LINK) 401 { 402 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 403 evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_INITIATE; 404 405 nfa_p2p_deallocate_conn_cb (xx); 406 407 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 408 } 409 else 410 { 411 /* 412 ** LLCP link has been deactivated before receiving CC or DM. 413 ** Return NFA_P2P_DISC_EVT to indicate failure of creating connection 414 */ 415 416 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 417 evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED; 418 419 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 420 421 P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated"); 422 } 423 } 424} 425 426/******************************************************************************* 427** 428** Function nfa_p2p_proc_llcp_disconnect_resp 429** 430** Description Processing rejected connection from peer 431** 432** 433** Returns None 434** 435*******************************************************************************/ 436void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA *p_data) 437{ 438 UINT8 local_sap, xx; 439 tNFA_P2P_EVT_DATA evt_data = {0}; 440 441 P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_resp ()"); 442 443 local_sap = p_data->disconnect_resp.local_sap; 444 445 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 446 { 447 if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC) 448 { 449 evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE; 450 } 451 else if ( (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_APP_REJECTED) 452 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_THIS) 453 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_ANY) 454 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_THIS) 455 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_ANY) ) 456 { 457 evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_REJECT; 458 } 459 else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_SERVICE) 460 { 461 evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_SERVICE; 462 } 463 464 if (evt_data.disc.reason == NFA_P2P_DISC_REASON_LOCAL_INITITATE) 465 { 466 xx = nfa_p2p_find_conn_cb (p_data->disconnect_resp.local_sap, 467 p_data->disconnect_resp.remote_sap); 468 469 if (xx != LLCP_MAX_DATA_LINK) 470 { 471 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 472 473 nfa_p2p_deallocate_conn_cb (xx); 474 475 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 476 } 477 else 478 { 479 P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_resp (): No connection found"); 480 } 481 } 482 else 483 { 484 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 485 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 486 } 487 } 488} 489 490/******************************************************************************* 491** 492** Function nfa_p2p_proc_llcp_congest 493** 494** Description Processing LLCP congestion event 495** 496** 497** Returns None 498** 499*******************************************************************************/ 500void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA *p_data) 501{ 502 UINT8 local_sap, remote_sap, xx; 503 tNFA_P2P_EVT_DATA evt_data; 504 505 local_sap = p_data->congest.local_sap; 506 remote_sap = p_data->congest.remote_sap; 507 508 evt_data.congest.link_type = p_data->congest.link_type; 509 evt_data.congest.is_congested = p_data->congest.is_congested; 510 511 if (p_data->congest.is_congested) 512 { 513 P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () START SAP=(0x%x,0x%x)", 514 local_sap, remote_sap); 515 516 } 517 else 518 { 519 P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () END SAP=(0x%x,0x%x)", 520 local_sap, remote_sap); 521 } 522 523 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 524 { 525 if (evt_data.congest.link_type == NFA_P2P_LLINK_TYPE) 526 { 527 evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 528 529 if ( (evt_data.congest.is_congested == FALSE) 530 &&(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED) ) 531 { 532 nfa_p2p_cb.sap_cb[local_sap].flags &= ~NFA_P2P_SAP_FLAG_LLINK_CONGESTED; 533 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 534 } 535 else if ( (evt_data.congest.is_congested == TRUE) 536 &&(!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)) ) 537 { 538 /* this is overall congestion due to high usage of buffer pool */ 539 nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED; 540 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 541 } 542 } 543 else 544 { 545 xx = nfa_p2p_find_conn_cb (local_sap, remote_sap); 546 547 if (xx != LLCP_MAX_DATA_LINK) 548 { 549 evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 550 551 if ( (evt_data.congest.is_congested == FALSE) 552 &&(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED) ) 553 { 554 nfa_p2p_cb.conn_cb[xx].flags &= ~NFA_P2P_CONN_FLAG_CONGESTED; 555 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 556 } 557 else if ( (evt_data.congest.is_congested == TRUE) 558 &&(!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)) ) 559 { 560 /* this is overall congestion due to high usage of buffer pool */ 561 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED; 562 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 563 } 564 } 565 else 566 { 567 P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_congestion (): No connection found"); 568 } 569 } 570 } 571} 572 573/******************************************************************************* 574** 575** Function nfa_p2p_proc_llcp_link_status 576** 577** Description Processing LLCP link status 578** 579** 580** Returns next state after processing this event 581** 582*******************************************************************************/ 583void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA *p_data) 584{ 585 UINT8 local_sap, xx; 586 tNFA_P2P_EVT_DATA evt_data; 587 588 P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_link_status () is_activated:%d", 589 p_data->link_status.is_activated); 590 591 local_sap = p_data->link_status.local_sap; 592 593 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 594 { 595 if (p_data->link_status.is_activated) 596 { 597 /* only for server */ 598 evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 599 evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu; 600 evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu; 601 602 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data); 603 } 604 else /* if LLCP link is deactivated */ 605 { 606 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) 607 { 608 if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) 609 &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)) 610 { 611 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 612 evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED; 613 614 nfa_p2p_deallocate_conn_cb (xx); 615 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 616 } 617 } 618 619 /* notify deactivation and clear flags */ 620 if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_SERVER) 621 { 622 evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 623 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data); 624 625 nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_SERVER; 626 } 627 else if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_CLIENT) 628 { 629 evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 630 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data); 631 632 nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT; 633 } 634 else /* if this is not registered service */ 635 { 636 nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL; 637 } 638 } 639 } 640} 641 642/******************************************************************************* 643** 644** Function nfa_p2p_reg_server 645** 646** Description Allocate a service as server and register to LLCP 647** 648** 649** Returns FALSE if need to keep buffer 650** 651*******************************************************************************/ 652BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg) 653{ 654 tNFA_P2P_EVT_DATA evt_data; 655 UINT8 server_sap; 656 657 P2P_TRACE_DEBUG0 ("nfa_p2p_reg_server ()"); 658 659 server_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap, 660 p_msg->api_reg_server.link_type, 661 p_msg->api_reg_server.service_name, 662 nfa_p2p_llcp_cback); 663 664 if (server_sap == LLCP_INVALID_SAP) 665 { 666 evt_data.reg_server.server_handle = NFA_HANDLE_INVALID; 667 evt_data.reg_server.server_sap = NFA_P2P_INVALID_SAP; 668 BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name), 669 p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN); 670 evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0; 671 672 p_msg->api_reg_server.p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data); 673 674 return TRUE; 675 } 676 677 /* if need to update WKS in LLCP Gen bytes */ 678 if (server_sap <= LLCP_UPPER_BOUND_WK_SAP) 679 { 680 nfa_p2p_enable_listening (NFA_ID_P2P, TRUE); 681 } 682 else if (!nfa_p2p_cb.is_p2p_listening) 683 { 684 nfa_p2p_enable_listening (NFA_ID_P2P, FALSE); 685 } 686 687 nfa_p2p_cb.sap_cb[server_sap].p_cback = p_msg->api_reg_server.p_cback; 688 nfa_p2p_cb.sap_cb[server_sap].flags = NFA_P2P_SAP_FLAG_SERVER; 689 690 evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap); 691 evt_data.reg_server.server_sap = server_sap; 692 BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name), 693 p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN); 694 evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0; 695 696 /* notify NFA_P2P_REG_SERVER_EVT to server */ 697 nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data); 698 699 /* if LLCP is already activated */ 700 if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) 701 { 702 evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | server_sap); 703 evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu; 704 evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu; 705 706 /* notify NFA_P2P_ACTIVATED_EVT to server */ 707 nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data); 708 } 709 710 return TRUE; 711} 712 713/******************************************************************************* 714** 715** Function nfa_p2p_reg_client 716** 717** Description Allocate a service as client and register to LLCP 718** 719** 720** Returns TRUE to deallocate buffer 721** 722*******************************************************************************/ 723BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg) 724{ 725 tNFA_P2P_EVT_DATA evt_data; 726 UINT8 local_sap; 727 728 P2P_TRACE_DEBUG0 ("nfa_p2p_reg_client ()"); 729 730 local_sap = LLCP_RegisterClient (p_msg->api_reg_client.link_type, 731 nfa_p2p_llcp_cback); 732 733 if (local_sap == LLCP_INVALID_SAP) 734 { 735 evt_data.reg_client.client_handle = NFA_HANDLE_INVALID; 736 p_msg->api_reg_client.p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data); 737 return TRUE; 738 } 739 740 nfa_p2p_cb.sap_cb[local_sap].p_cback = p_msg->api_reg_client.p_cback; 741 nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT; 742 743 evt_data.reg_client.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap); 744 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data); 745 746 /* if LLCP is already activated */ 747 if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) 748 { 749 evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 750 evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu; 751 evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu; 752 753 /* notify NFA_P2P_ACTIVATED_EVT to client */ 754 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data); 755 } 756 757 return TRUE; 758} 759 760/******************************************************************************* 761** 762** Function nfa_p2p_dereg 763** 764** Description Deallocate a service as server or client and deregister to LLCP 765** LLCP will deallocate data link connection created by this server 766** 767** Returns TRUE to deallocate buffer 768** 769*******************************************************************************/ 770BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg) 771{ 772 UINT8 local_sap, xx; 773 774 P2P_TRACE_DEBUG0 ("nfa_p2p_dereg ()"); 775 776 local_sap = (UINT8) (p_msg->api_dereg.handle & NFA_HANDLE_MASK); 777 778 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 779 { 780 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) 781 { 782 if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) 783 &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap) ) 784 { 785 nfa_p2p_deallocate_conn_cb (xx); 786 } 787 } 788 } 789 790 LLCP_Deregister (local_sap); 791 nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL; 792 793 if (nfa_p2p_cb.is_p2p_listening) 794 { 795 /* check if this is the last server on NFA P2P */ 796 for (xx = 0; xx < NFA_P2P_NUM_SAP; xx++) 797 { 798 if ( (nfa_p2p_cb.sap_cb[xx].p_cback) 799 &&(nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_SERVER) ) 800 { 801 break; 802 } 803 } 804 805 if (xx >= NFA_P2P_NUM_SAP) 806 { 807 /* if need to update WKS in LLCP Gen bytes */ 808 if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) 809 nfa_p2p_disable_listening (NFA_ID_P2P, TRUE); 810 else 811 nfa_p2p_disable_listening (NFA_ID_P2P, FALSE); 812 } 813 /* if need to update WKS in LLCP Gen bytes */ 814 else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) 815 { 816 nfa_p2p_enable_listening (NFA_ID_P2P, TRUE); 817 } 818 } 819 820 return TRUE; 821} 822 823/******************************************************************************* 824** 825** Function nfa_p2p_accept_connection 826** 827** Description Connection Confirm from local application 828** 829** 830** Returns TRUE to deallocate buffer 831** 832*******************************************************************************/ 833BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg) 834{ 835 UINT8 xx; 836 tLLCP_CONNECTION_PARAMS params; 837 838 P2P_TRACE_DEBUG0 ("nfa_p2p_accept_connection ()"); 839 840 xx = (UINT8) (p_msg->api_accept.conn_handle & NFA_HANDLE_MASK); 841 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 842 843 params.miu = p_msg->api_accept.miu; 844 params.rw = p_msg->api_accept.rw; 845 params.sn[0] = 0; 846 847 LLCP_ConnectCfm (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, ¶ms); 848 849 return TRUE; 850} 851 852/******************************************************************************* 853** 854** Function nfa_p2p_reject_connection 855** 856** Description Reject connection by local application 857** 858** 859** Returns TRUE to deallocate buffer 860** 861*******************************************************************************/ 862BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg) 863{ 864 UINT8 xx; 865 866 P2P_TRACE_DEBUG0 ("nfa_p2p_reject_connection ()"); 867 868 xx = (UINT8) (p_msg->api_reject.conn_handle & NFA_HANDLE_MASK); 869 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 870 871 LLCP_ConnectReject (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, 872 LLCP_SAP_DM_REASON_APP_REJECTED); 873 874 /* no need to deregister service on LLCP */ 875 nfa_p2p_deallocate_conn_cb (xx); 876 877 return TRUE; 878} 879 880/******************************************************************************* 881** 882** Function nfa_p2p_disconnect 883** 884** Description Disconnect data link connection by local application 885** 886** 887** Returns TRUE to deallocate buffer 888** 889*******************************************************************************/ 890BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg) 891{ 892 UINT8 local_sap, xx; 893 tLLCP_STATUS status; 894 tNFA_P2P_EVT_DATA evt_data; 895 896 P2P_TRACE_DEBUG0 ("nfa_p2p_disconnect ()"); 897 898 xx = (UINT8) (p_msg->api_disconnect.conn_handle & NFA_HANDLE_MASK); 899 900 /* if this is for data link connection */ 901 if (xx & NFA_P2P_HANDLE_FLAG_CONN) 902 { 903 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 904 905 status = LLCP_DisconnectReq (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, 906 p_msg->api_disconnect.flush); 907 908 if (status == LLCP_STATUS_SUCCESS) 909 { 910 /* wait for disconnect response if successful */ 911 return TRUE; 912 } 913 else 914 { 915 /* 916 ** while we are waiting for connect confirm, 917 ** we cannot sent DISC because we don't know DSAP yet 918 */ 919 local_sap = nfa_p2p_cb.conn_cb[xx].local_sap; 920 921 if (nfa_p2p_cb.sap_cb[local_sap].p_cback) 922 { 923 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 924 evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE; 925 926 nfa_p2p_deallocate_conn_cb (xx); 927 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 928 } 929 } 930 } 931 else 932 { 933 P2P_TRACE_ERROR0 ("Handle is not for Data link connection"); 934 } 935 936 return TRUE; 937} 938 939/******************************************************************************* 940** 941** Function nfa_p2p_create_data_link_connection 942** 943** Description Create data link connection 944** 945** 946** Returns TRUE to deallocate buffer 947** 948*******************************************************************************/ 949BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg) 950{ 951 UINT8 local_sap; 952 tNFA_P2P_EVT_DATA evt_data; 953 tLLCP_CONNECTION_PARAMS conn_params; 954 tLLCP_STATUS status; 955 956 P2P_TRACE_DEBUG0 ("nfa_p2p_create_data_link_connection ()"); 957 958 local_sap = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK); 959 960 conn_params.miu = p_msg->api_connect.miu; 961 conn_params.rw = p_msg->api_connect.rw; 962 963 /* NFA_P2pConnectBySap () */ 964 if (p_msg->api_connect.dsap != LLCP_INVALID_SAP) 965 { 966 conn_params.sn[0] = 0; 967 status = LLCP_ConnectReq (local_sap, p_msg->api_connect.dsap, &conn_params); 968 } 969 /* NFA_P2pConnectByName () */ 970 else 971 { 972 BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn), 973 p_msg->api_connect.service_name, LLCP_MAX_SN_LEN); 974 conn_params.sn[LLCP_MAX_SN_LEN] = 0; 975 976 status = LLCP_ConnectReq (local_sap, LLCP_SAP_SDP, &conn_params); 977 } 978 979 if (status != LLCP_STATUS_SUCCESS) 980 { 981 evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 982 evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION; 983 984 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data); 985 } 986 987 return TRUE; 988} 989 990/******************************************************************************* 991** 992** Function nfa_p2p_send_ui 993** 994** Description Send UI PDU 995** 996** 997** Returns TRUE to deallocate buffer 998** 999*******************************************************************************/ 1000BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg) 1001{ 1002 UINT8 local_sap; 1003 tLLCP_STATUS status; 1004 tNFA_P2P_EVT_DATA evt_data; 1005 1006 P2P_TRACE_DEBUG0 ("nfa_p2p_send_ui ()"); 1007 1008 local_sap = (UINT8) (p_msg->api_send_ui.handle & NFA_HANDLE_MASK); 1009 1010 /* decrease number of tx UI PDU which is not processed by NFA for congestion control */ 1011 if (nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu) 1012 nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu--; 1013 1014 if (nfa_p2p_cb.total_pending_ui_pdu) 1015 nfa_p2p_cb.total_pending_ui_pdu--; 1016 1017 status = LLCP_SendUI (local_sap, 1018 p_msg->api_send_ui.dsap, 1019 p_msg->api_send_ui.p_msg); 1020 1021 if (status == LLCP_STATUS_CONGESTED) 1022 { 1023 if (!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)) 1024 { 1025 nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED; 1026 1027 /* notify that this logical link is congested */ 1028 evt_data.congest.link_type = NFA_P2P_LLINK_TYPE; 1029 evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap); 1030 evt_data.congest.is_congested = TRUE; 1031 1032 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 1033 } 1034 } 1035 1036 return TRUE; 1037} 1038 1039/******************************************************************************* 1040** 1041** Function nfa_p2p_send_data 1042** 1043** Description Send I PDU 1044** 1045** 1046** Returns TRUE to deallocate buffer 1047** 1048*******************************************************************************/ 1049BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg) 1050{ 1051 tNFA_P2P_EVT_DATA evt_data; 1052 tLLCP_STATUS status; 1053 UINT8 xx; 1054 1055 P2P_TRACE_DEBUG0 ("nfa_p2p_send_data ()"); 1056 1057 xx = (UINT8) (p_msg->api_send_data.conn_handle & NFA_HANDLE_MASK); 1058 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 1059 1060 /* decrease number of tx I PDU which is not processed by NFA for congestion control */ 1061 if (nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu) 1062 nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu--; 1063 1064 if (nfa_p2p_cb.total_pending_i_pdu) 1065 nfa_p2p_cb.total_pending_i_pdu--; 1066 1067 status = LLCP_SendData (nfa_p2p_cb.conn_cb[xx].local_sap, 1068 nfa_p2p_cb.conn_cb[xx].remote_sap, 1069 p_msg->api_send_data.p_msg); 1070 1071 if (status == LLCP_STATUS_CONGESTED) 1072 { 1073 if (!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)) 1074 { 1075 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED; 1076 1077 /* notify that this data link is congested */ 1078 evt_data.congest.link_type = NFA_P2P_DLINK_TYPE; 1079 evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx); 1080 evt_data.congest.is_congested = TRUE; 1081 1082 nfa_p2p_cb.sap_cb[nfa_p2p_cb.conn_cb[xx].local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data); 1083 } 1084 } 1085 1086 return TRUE; 1087} 1088 1089/******************************************************************************* 1090** 1091** Function nfa_p2p_set_local_busy 1092** 1093** Description Set or reset local busy 1094** 1095** 1096** Returns TRUE to deallocate buffer 1097** 1098*******************************************************************************/ 1099BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg) 1100{ 1101 UINT8 xx; 1102 1103 P2P_TRACE_DEBUG0 ("nfa_p2p_set_local_busy ()"); 1104 1105 xx = (UINT8) (p_msg->api_local_busy.conn_handle & NFA_HANDLE_MASK); 1106 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 1107 1108 LLCP_SetLocalBusyStatus (nfa_p2p_cb.conn_cb[xx].local_sap, 1109 nfa_p2p_cb.conn_cb[xx].remote_sap, 1110 p_msg->api_local_busy.is_busy); 1111 1112 return TRUE; 1113} 1114 1115/******************************************************************************* 1116** 1117** Function nfa_p2p_get_link_info 1118** 1119** Description Get WKS of remote and link MIU 1120** 1121** 1122** Returns TRUE to deallocate buffer 1123** 1124*******************************************************************************/ 1125BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg) 1126{ 1127 tNFA_P2P_EVT_DATA evt_data; 1128 UINT8 local_sap; 1129 1130 P2P_TRACE_DEBUG0 ("nfa_p2p_get_link_info ()"); 1131 1132 evt_data.link_info.handle = p_msg->api_link_info.handle; 1133 evt_data.link_info.wks = LLCP_GetRemoteWKS (); 1134 evt_data.link_info.local_link_miu = nfa_p2p_cb.local_link_miu; 1135 evt_data.link_info.remote_link_miu = nfa_p2p_cb.remote_link_miu; 1136 1137 local_sap = (UINT8) (p_msg->api_link_info.handle & NFA_HANDLE_MASK); 1138 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_LINK_INFO_EVT, &evt_data); 1139 1140 return TRUE; 1141} 1142 1143/******************************************************************************* 1144** 1145** Function nfa_p2p_get_remote_sap 1146** 1147** Description Get remote SAP 1148** 1149** 1150** Returns TRUE to deallocate buffer 1151** 1152*******************************************************************************/ 1153BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg) 1154{ 1155 tNFA_P2P_EVT_DATA evt_data; 1156 UINT8 local_sap; 1157 1158 P2P_TRACE_DEBUG0 ("nfa_p2p_get_remote_sap ()"); 1159 1160 local_sap = (UINT8) (p_msg->api_remote_sap.handle & NFA_HANDLE_MASK); 1161 1162 if (!nfa_p2p_start_sdp (p_msg->api_remote_sap.service_name, 1163 local_sap)) 1164 { 1165 evt_data.sdp.handle = p_msg->api_remote_sap.handle; 1166 evt_data.sdp.remote_sap = 0x00; 1167 nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data); 1168 } 1169 1170 return TRUE; 1171} 1172 1173/******************************************************************************* 1174** 1175** Function nfa_p2p_set_llcp_cfg 1176** 1177** Description Set LLCP configuration 1178** 1179** 1180** Returns TRUE to deallocate buffer 1181** 1182*******************************************************************************/ 1183BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg) 1184{ 1185 LLCP_SetConfig (p_msg->api_set_llcp_cfg.link_miu, 1186 p_msg->api_set_llcp_cfg.opt, 1187 p_msg->api_set_llcp_cfg.wt, 1188 p_msg->api_set_llcp_cfg.link_timeout, 1189 p_msg->api_set_llcp_cfg.inact_timeout_init, 1190 p_msg->api_set_llcp_cfg.inact_timeout_target, 1191 p_msg->api_set_llcp_cfg.symm_delay, 1192 p_msg->api_set_llcp_cfg.data_link_timeout, 1193 p_msg->api_set_llcp_cfg.delay_first_pdu_timeout); 1194 1195 return TRUE; 1196} 1197