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