1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 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 file contains main functions to support PAN profile 22 * commands and events. 23 * 24 ******************************************************************************/ 25 26 #include <string.h> 27 #include "gki.h" 28 #include "bt_types.h" 29 #include "bt_utils.h" 30 #include "bnep_api.h" 31 #include "pan_api.h" 32 #include "pan_int.h" 33 #include "sdp_api.h" 34 #include "sdpdefs.h" 35 #include "l2c_api.h" 36 #include "hcidefs.h" 37 38 39 #if PAN_DYNAMIC_MEMORY == FALSE 40 tPAN_CB pan_cb; 41 #endif 42 43 #define UUID_CONSTANT_PART 12 44 UINT8 constant_pan_uuid[UUID_CONSTANT_PART] = {0, 0, 0x10, 0, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}; 45 46 47 /******************************************************************************* 48 ** 49 ** Function pan_register_with_bnep 50 ** 51 ** Description This function registers PAN profile with BNEP 52 ** 53 ** Parameters: none 54 ** 55 ** Returns none 56 ** 57 *******************************************************************************/ 58 void pan_register_with_bnep (void) 59 { 60 tBNEP_REGISTER reg_info; 61 62 memset (®_info, 0, sizeof (tBNEP_REGISTER)); 63 64 reg_info.p_conn_ind_cb = pan_conn_ind_cb; 65 reg_info.p_conn_state_cb = pan_connect_state_cb; 66 reg_info.p_data_buf_cb = pan_data_buf_ind_cb; 67 reg_info.p_data_ind_cb = NULL; 68 reg_info.p_tx_data_flow_cb = pan_tx_data_flow_cb; 69 reg_info.p_filter_ind_cb = pan_proto_filt_ind_cb; 70 reg_info.p_mfilter_ind_cb = pan_mcast_filt_ind_cb; 71 72 BNEP_Register (®_info); 73 } 74 75 76 /******************************************************************************* 77 ** 78 ** Function pan_conn_ind_cb 79 ** 80 ** Description This function is registered with BNEP as connection indication 81 ** callback. BNEP will call this when there is connection 82 ** request from the peer. PAN should call BNEP_ConnectResp to 83 ** indicate whether to accept the connection or reject 84 ** 85 ** Parameters: handle - handle for the connection 86 ** p_bda - BD Addr of the peer requesting the connection 87 ** remote_uuid - UUID of the source role (peer device role) 88 ** local_uuid - UUID of the destination role (local device role) 89 ** is_role_change - Flag to indicate that it is a role change 90 ** 91 ** Returns none 92 ** 93 *******************************************************************************/ 94 void pan_conn_ind_cb (UINT16 handle, 95 BD_ADDR p_bda, 96 tBT_UUID *remote_uuid, 97 tBT_UUID *local_uuid, 98 BOOLEAN is_role_change) 99 { 100 tPAN_CONN *pcb; 101 UINT8 req_role; 102 BOOLEAN wrong_uuid; 103 104 /* 105 ** If we are in GN or NAP role and have one or more 106 ** active connections and the received connection is 107 ** for user role reject it. 108 ** If we are in user role with one connection active 109 ** reject the connection. 110 ** Allocate PCB and store the parameters 111 ** Make bridge request to the host system if connection 112 ** is for NAP 113 */ 114 wrong_uuid = FALSE; 115 #if (defined (BNEP_SUPPORTS_ALL_UUID_LENGTHS) && BNEP_SUPPORTS_ALL_UUID_LENGTHS == TRUE) 116 if (remote_uuid->len == 16) 117 { 118 /* 119 ** If the UUID is 16 bytes forst two bytes should be zeros 120 ** and last 12 bytes should match the spec defined constant value 121 */ 122 if (memcmp (constant_pan_uuid, remote_uuid->uu.uuid128 + 4, UUID_CONSTANT_PART)) 123 wrong_uuid = TRUE; 124 125 if (remote_uuid->uu.uuid128[0] || remote_uuid->uu.uuid128[1]) 126 wrong_uuid = TRUE; 127 128 /* Extract the 16 bit equivalent of the UUID */ 129 remote_uuid->uu.uuid16 = (UINT16)((remote_uuid->uu.uuid128[2] << 8) | remote_uuid->uu.uuid128[3]); 130 remote_uuid->len = 2; 131 } 132 if (remote_uuid->len == 4) 133 { 134 /* First two bytes should be zeros */ 135 if (remote_uuid->uu.uuid32 & 0xFFFF0000) 136 wrong_uuid = TRUE; 137 138 remote_uuid->uu.uuid16 = (UINT16)remote_uuid->uu.uuid32; 139 remote_uuid->len = 2; 140 } 141 142 if (wrong_uuid) 143 { 144 PAN_TRACE_ERROR ("PAN Connection failed because of wrong remote UUID "); 145 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID); 146 return; 147 } 148 149 wrong_uuid = FALSE; 150 if (local_uuid->len == 16) 151 { 152 /* 153 ** If the UUID is 16 bytes forst two bytes should be zeros 154 ** and last 12 bytes should match the spec defined constant value 155 */ 156 if (memcmp (constant_pan_uuid, local_uuid->uu.uuid128 + 4, UUID_CONSTANT_PART)) 157 wrong_uuid = TRUE; 158 159 if (local_uuid->uu.uuid128[0] || local_uuid->uu.uuid128[1]) 160 wrong_uuid = TRUE; 161 162 /* Extract the 16 bit equivalent of the UUID */ 163 local_uuid->uu.uuid16 = (UINT16)((local_uuid->uu.uuid128[2] << 8) | local_uuid->uu.uuid128[3]); 164 local_uuid->len = 2; 165 } 166 if (local_uuid->len == 4) 167 { 168 /* First two bytes should be zeros */ 169 if (local_uuid->uu.uuid32 & 0xFFFF0000) 170 wrong_uuid = TRUE; 171 172 local_uuid->uu.uuid16 = (UINT16)local_uuid->uu.uuid32; 173 local_uuid->len = 2; 174 } 175 176 if (wrong_uuid) 177 { 178 PAN_TRACE_ERROR ("PAN Connection failed because of wrong local UUID "); 179 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 180 return; 181 } 182 183 PAN_TRACE_EVENT ("pan_conn_ind_cb - for handle %d, current role %d, dst uuid 0x%x, src uuid 0x%x, role change %s", 184 handle, pan_cb.role, local_uuid->uu.uuid16, remote_uuid->uu.uuid16, is_role_change?"YES":"NO"); 185 /* The acceptable UUID size is only 2 */ 186 if (remote_uuid->len != 2) 187 { 188 PAN_TRACE_ERROR ("PAN Connection failed because of wrong UUID size %d", remote_uuid->len); 189 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_UUID_SIZE); 190 return; 191 } 192 #endif 193 194 /* Check if the source UUID is a valid one */ 195 if (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU && 196 remote_uuid->uu.uuid16 != UUID_SERVCLASS_NAP && 197 remote_uuid->uu.uuid16 != UUID_SERVCLASS_GN) 198 { 199 PAN_TRACE_ERROR ("Src UUID 0x%x is not valid", remote_uuid->uu.uuid16); 200 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID); 201 return; 202 } 203 204 /* Check if the destination UUID is a valid one */ 205 if (local_uuid->uu.uuid16 != UUID_SERVCLASS_PANU && 206 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP && 207 local_uuid->uu.uuid16 != UUID_SERVCLASS_GN) 208 { 209 PAN_TRACE_ERROR ("Dst UUID 0x%x is not valid", remote_uuid->uu.uuid16); 210 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 211 return; 212 } 213 214 /* Check if currently we support the destination role requested */ 215 if (((!(pan_cb.role & UUID_SERVCLASS_PANU)) 216 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) || 217 ((!(pan_cb.role & UUID_SERVCLASS_GN)) 218 && local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) || 219 ((!(pan_cb.role & UUID_SERVCLASS_NAP)) 220 && local_uuid->uu.uuid16 == UUID_SERVCLASS_NAP)) 221 { 222 PAN_TRACE_ERROR ("PAN Connection failed because of unsupported destination UUID 0x%x", local_uuid->uu.uuid16); 223 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 224 return; 225 } 226 227 /* Requested destination role is */ 228 if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 229 req_role = PAN_ROLE_CLIENT; 230 else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) 231 req_role = PAN_ROLE_GN_SERVER; 232 else 233 req_role = PAN_ROLE_NAP_SERVER; 234 235 /* If the connection indication is for the existing connection 236 ** Check if the new destination role is acceptable 237 */ 238 pcb = pan_get_pcb_by_handle (handle); 239 if (pcb) 240 { 241 if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 242 { 243 /* There are connections other than this one 244 ** so we cann't accept PANU role. Reject 245 */ 246 PAN_TRACE_ERROR ("Dst UUID should be either GN or NAP only because there are other connections"); 247 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 248 return; 249 } 250 251 /* If it is already in connected state check for bridging status */ 252 if (pcb->con_state == PAN_STATE_CONNECTED) 253 { 254 PAN_TRACE_EVENT ("PAN Role changing New Src 0x%x Dst 0x%x", 255 remote_uuid->uu.uuid16, local_uuid->uu.uuid16); 256 257 pcb->prv_src_uuid = pcb->src_uuid; 258 pcb->prv_dst_uuid = pcb->dst_uuid; 259 260 if (pcb->src_uuid == UUID_SERVCLASS_NAP && 261 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP) 262 { 263 /* Remove bridging */ 264 if (pan_cb.pan_bridge_req_cb) 265 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); 266 } 267 } 268 /* Set the latest active PAN role */ 269 pan_cb.active_role = req_role; 270 pcb->src_uuid = local_uuid->uu.uuid16; 271 pcb->dst_uuid = remote_uuid->uu.uuid16; 272 BNEP_ConnectResp (handle, BNEP_SUCCESS); 273 return; 274 } 275 else 276 { 277 /* If this a new connection and destination is PANU role and 278 ** we already have a connection then reject the request. 279 ** If we have a connection in PANU role then reject it 280 */ 281 if (pan_cb.num_conns && 282 (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU || 283 pan_cb.active_role == PAN_ROLE_CLIENT)) 284 { 285 PAN_TRACE_ERROR ("PAN already have a connection and can't be user"); 286 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 287 return; 288 } 289 } 290 291 /* This is a new connection */ 292 PAN_TRACE_DEBUG ("New connection indication for handle %d", handle); 293 pcb = pan_allocate_pcb (p_bda, handle); 294 if (!pcb) 295 { 296 PAN_TRACE_ERROR ("PAN no control block for new connection"); 297 BNEP_ConnectResp (handle, BNEP_CONN_FAILED); 298 return; 299 } 300 301 PAN_TRACE_EVENT ("PAN connection destination UUID is 0x%x", local_uuid->uu.uuid16); 302 /* Set the latest active PAN role */ 303 pan_cb.active_role = req_role; 304 pcb->src_uuid = local_uuid->uu.uuid16; 305 pcb->dst_uuid = remote_uuid->uu.uuid16; 306 pcb->con_state = PAN_STATE_CONN_START; 307 pan_cb.num_conns++; 308 309 BNEP_ConnectResp (handle, BNEP_SUCCESS); 310 return; 311 } 312 313 314 /******************************************************************************* 315 ** 316 ** Function pan_connect_state_cb 317 ** 318 ** Description This function is registered with BNEP as connection state 319 ** change callback. BNEP will call this when the connection 320 ** is established successfully or terminated 321 ** 322 ** Parameters: handle - handle for the connection given in the connection 323 ** indication callback 324 ** rem_bda - remote device bd addr 325 ** result - indicates whether the connection is up or down 326 ** BNEP_SUCCESS if the connection is up 327 ** all other values indicates appropriate errors 328 ** is_role_change - flag to indicate that it is a role change 329 ** 330 ** Returns none 331 ** 332 *******************************************************************************/ 333 void pan_connect_state_cb (UINT16 handle, BD_ADDR rem_bda, tBNEP_RESULT result, BOOLEAN is_role_change) 334 { 335 tPAN_CONN *pcb; 336 UINT8 peer_role; 337 UNUSED(rem_bda); 338 339 PAN_TRACE_EVENT ("pan_connect_state_cb - for handle %d, result %d", handle, result); 340 pcb = pan_get_pcb_by_handle (handle); 341 if (!pcb) 342 { 343 PAN_TRACE_ERROR ("PAN State change indication for wrong handle %d", handle); 344 return; 345 } 346 347 /* If the connection is getting terminated remove bridging */ 348 if (result != BNEP_SUCCESS) 349 { 350 /* Inform the application that connection is down */ 351 if (pan_cb.pan_conn_state_cb) 352 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, result, is_role_change, PAN_ROLE_INACTIVE, PAN_ROLE_INACTIVE); 353 354 /* Check if this failure is for role change only */ 355 if (pcb->con_state != PAN_STATE_CONNECTED && 356 (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED)) 357 { 358 /* restore the original values */ 359 PAN_TRACE_EVENT ("restoring the connection state to active"); 360 pcb->con_state = PAN_STATE_CONNECTED; 361 pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED); 362 363 pcb->src_uuid = pcb->prv_src_uuid; 364 pcb->dst_uuid = pcb->prv_dst_uuid; 365 pan_cb.active_role = pan_cb.prv_active_role; 366 367 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb) 368 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE); 369 370 return; 371 } 372 373 if (pcb->con_state == PAN_STATE_CONNECTED) 374 { 375 /* If the connections destination role is NAP remove bridging */ 376 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb) 377 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); 378 } 379 380 pan_cb.num_conns--; 381 pan_release_pcb (pcb); 382 return; 383 } 384 385 /* Requested destination role is */ 386 if (pcb->src_uuid == UUID_SERVCLASS_PANU) 387 pan_cb.active_role = PAN_ROLE_CLIENT; 388 else if (pcb->src_uuid == UUID_SERVCLASS_GN) 389 pan_cb.active_role = PAN_ROLE_GN_SERVER; 390 else 391 pan_cb.active_role = PAN_ROLE_NAP_SERVER; 392 393 if (pcb->dst_uuid == UUID_SERVCLASS_PANU) 394 peer_role = PAN_ROLE_CLIENT; 395 else if (pcb->dst_uuid == UUID_SERVCLASS_GN) 396 peer_role = PAN_ROLE_GN_SERVER; 397 else 398 peer_role = PAN_ROLE_NAP_SERVER; 399 400 pcb->con_state = PAN_STATE_CONNECTED; 401 402 /* Inform the application that connection is down */ 403 if (pan_cb.pan_conn_state_cb) 404 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, PAN_SUCCESS, is_role_change, pan_cb.active_role, peer_role); 405 406 /* Create bridge if the destination role is NAP */ 407 if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) 408 { 409 PAN_TRACE_EVENT ("PAN requesting for bridge"); 410 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE); 411 } 412 } 413 414 415 /******************************************************************************* 416 ** 417 ** Function pan_data_ind_cb 418 ** 419 ** Description This function is registered with BNEP as data indication 420 ** callback. BNEP will call this when the peer sends any data 421 ** on this connection 422 ** 423 ** Parameters: handle - handle for the connection 424 ** src - source BD Addr 425 ** dst - destination BD Addr 426 ** protocol - Network protocol of the Eth packet 427 ** p_data - pointer to the data 428 ** len - length of the data 429 ** fw_ext_present - to indicate whether the data contains any 430 ** extension headers before the payload 431 ** 432 ** Returns none 433 ** 434 *******************************************************************************/ 435 void pan_data_ind_cb (UINT16 handle, 436 UINT8 *src, 437 UINT8 *dst, 438 UINT16 protocol, 439 UINT8 *p_data, 440 UINT16 len, 441 BOOLEAN ext) 442 { 443 tPAN_CONN *pcb; 444 UINT16 i; 445 BOOLEAN forward; 446 447 /* 448 ** Check the connection status 449 ** If the destination address is MAC broadcast send on all links 450 ** except on the one received 451 ** If the destination uuid is for NAP send to host system also 452 ** If the destination address is one of the devices connected 453 ** send the packet to over that link 454 ** If the destination address is unknown and destination uuid is NAP 455 ** send it to the host system 456 */ 457 458 PAN_TRACE_EVENT ("pan_data_ind_cb - for handle %d", handle); 459 pcb = pan_get_pcb_by_handle (handle); 460 if (!pcb) 461 { 462 PAN_TRACE_ERROR ("PAN Data indication for wrong handle %d", handle); 463 return; 464 } 465 466 if (pcb->con_state != PAN_STATE_CONNECTED) 467 { 468 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d", 469 pcb->con_state, handle); 470 return; 471 } 472 473 /* Check if it is broadcast packet */ 474 if (dst[0] & 0x01) 475 { 476 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x", 477 handle, pcb->src_uuid); 478 for (i=0; i<MAX_PAN_CONNS; i++) 479 { 480 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 481 pan_cb.pcb[i].handle != handle && 482 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 483 { 484 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 485 } 486 } 487 488 if (pan_cb.pan_data_ind_cb) 489 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, TRUE); 490 491 return; 492 } 493 494 /* Check if it is for any other PAN connection */ 495 for (i=0; i<MAX_PAN_CONNS; i++) 496 { 497 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 498 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 499 { 500 if (memcmp (pan_cb.pcb[i].rem_bda, dst, BD_ADDR_LEN) == 0) 501 { 502 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 503 return; 504 } 505 } 506 } 507 508 if (pcb->src_uuid == UUID_SERVCLASS_NAP) 509 forward = TRUE; 510 else 511 forward = FALSE; 512 513 /* Send it over the LAN or give it to host software */ 514 if (pan_cb.pan_data_ind_cb) 515 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 516 517 return; 518 } 519 520 521 /******************************************************************************* 522 ** 523 ** Function pan_data_buf_ind_cb 524 ** 525 ** Description This function is registered with BNEP as data buffer indication 526 ** callback. BNEP will call this when the peer sends any data 527 ** on this connection. PAN is responsible to release the buffer 528 ** 529 ** Parameters: handle - handle for the connection 530 ** src - source BD Addr 531 ** dst - destination BD Addr 532 ** protocol - Network protocol of the Eth packet 533 ** p_buf - pointer to the data buffer 534 ** ext - to indicate whether the data contains any 535 ** extension headers before the payload 536 ** 537 ** Returns none 538 ** 539 *******************************************************************************/ 540 void pan_data_buf_ind_cb (UINT16 handle, 541 UINT8 *src, 542 UINT8 *dst, 543 UINT16 protocol, 544 BT_HDR *p_buf, 545 BOOLEAN ext) 546 { 547 tPAN_CONN *pcb, *dst_pcb; 548 tBNEP_RESULT result; 549 UINT16 i, len; 550 UINT8 *p_data; 551 BOOLEAN forward = FALSE; 552 553 /* Check if the connection is in right state */ 554 pcb = pan_get_pcb_by_handle (handle); 555 if (!pcb) 556 { 557 PAN_TRACE_ERROR ("PAN Data buffer indication for wrong handle %d", handle); 558 GKI_freebuf (p_buf); 559 return; 560 } 561 562 if (pcb->con_state != PAN_STATE_CONNECTED) 563 { 564 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d", 565 pcb->con_state, handle); 566 GKI_freebuf (p_buf); 567 return; 568 } 569 570 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 571 len = p_buf->len; 572 573 PAN_TRACE_EVENT ("pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d", 574 handle, protocol, len, ext); 575 576 if (pcb->src_uuid == UUID_SERVCLASS_NAP) 577 forward = TRUE; 578 else 579 forward = FALSE; 580 581 /* Check if it is broadcast or multicast packet */ 582 if (pcb->src_uuid != UUID_SERVCLASS_PANU) 583 { 584 if (dst[0] & 0x01) 585 { 586 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x", 587 handle, pcb->src_uuid); 588 for (i=0; i<MAX_PAN_CONNS; i++) 589 { 590 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 591 pan_cb.pcb[i].handle != handle && 592 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 593 { 594 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 595 } 596 } 597 598 if (pan_cb.pan_data_buf_ind_cb) 599 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward); 600 else if (pan_cb.pan_data_ind_cb) 601 { 602 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 603 GKI_freebuf (p_buf); 604 } 605 606 return; 607 } 608 609 /* Check if it is for any other PAN connection */ 610 dst_pcb = pan_get_pcb_by_addr (dst); 611 if (dst_pcb) 612 { 613 PAN_TRACE_EVENT ("pan_data_buf_ind_cb - destination PANU found and sending the data"); 614 result = BNEP_WriteBuf (dst_pcb->handle, dst, p_buf, protocol, src, ext); 615 if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD) 616 PAN_TRACE_ERROR ("Failed to write data for PAN connection handle %d", dst_pcb->handle); 617 return; 618 } 619 } 620 621 /* Send it over the LAN or give it to host software */ 622 if (pan_cb.pan_data_buf_ind_cb) 623 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward); 624 else if (pan_cb.pan_data_ind_cb) 625 { 626 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 627 GKI_freebuf (p_buf); 628 } 629 else 630 GKI_freebuf (p_buf); 631 632 return; 633 } 634 635 /******************************************************************************* 636 ** 637 ** Function pan_proto_filt_ind_cb 638 ** 639 ** Description This function is registered with BNEP to receive tx data 640 ** flow status 641 ** 642 ** Parameters: handle - handle for the connection 643 ** event - flow status 644 ** 645 ** Returns none 646 ** 647 *******************************************************************************/ 648 void pan_tx_data_flow_cb (UINT16 handle, 649 tBNEP_RESULT event) 650 { 651 652 if (pan_cb.pan_tx_data_flow_cb) 653 (*pan_cb.pan_tx_data_flow_cb) (handle, event); 654 655 return; 656 } 657 658 /******************************************************************************* 659 ** 660 ** Function pan_proto_filt_ind_cb 661 ** 662 ** Description This function is registered with BNEP as proto filter indication 663 ** callback. BNEP will call this when the peer sends any protocol 664 ** filter set for the connection or to indicate the result of the 665 ** protocol filter set by the local device 666 ** 667 ** Parameters: handle - handle for the connection 668 ** indication - TRUE if this is indication 669 ** FALSE if it is called to give the result of local 670 ** device protocol filter set 671 ** result - This gives the result of the filter set operation 672 ** num_filters - number of filters set by the peer device 673 ** p_filters - pointer to the filters set by the peer device 674 ** 675 ** Returns none 676 ** 677 *******************************************************************************/ 678 void pan_proto_filt_ind_cb (UINT16 handle, 679 BOOLEAN indication, 680 tBNEP_RESULT result, 681 UINT16 num_filters, 682 UINT8 *p_filters) 683 { 684 #if (defined (BNEP_SUPPORTS_PROT_FILTERS) && BNEP_SUPPORTS_PROT_FILTERS == TRUE) 685 PAN_TRACE_EVENT ("pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, num %d", 686 handle, indication, result, num_filters); 687 688 if (pan_cb.pan_pfilt_ind_cb) 689 (*pan_cb.pan_pfilt_ind_cb) (handle, indication, result, num_filters, p_filters); 690 #endif 691 692 return; 693 } 694 695 696 /******************************************************************************* 697 ** 698 ** Function pan_mcast_filt_ind_cb 699 ** 700 ** Description This function is registered with BNEP as mcast filter indication 701 ** callback. BNEP will call this when the peer sends any multicast 702 ** filter set for the connection or to indicate the result of the 703 ** multicast filter set by the local device 704 ** 705 ** Parameters: handle - handle for the connection 706 ** indication - TRUE if this is indication 707 ** FALSE if it is called to give the result of local 708 ** device multicast filter set 709 ** result - This gives the result of the filter set operation 710 ** num_filters - number of filters set by the peer device 711 ** p_filters - pointer to the filters set by the peer device 712 ** 713 ** Returns none 714 ** 715 *******************************************************************************/ 716 void pan_mcast_filt_ind_cb (UINT16 handle, 717 BOOLEAN indication, 718 tBNEP_RESULT result, 719 UINT16 num_filters, 720 UINT8 *p_filters) 721 { 722 #if (defined (BNEP_SUPPORTS_MULTI_FILTERS) && BNEP_SUPPORTS_MULTI_FILTERS == TRUE) 723 PAN_TRACE_EVENT ("pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, num %d", 724 handle, indication, result, num_filters); 725 726 if (pan_cb.pan_mfilt_ind_cb) 727 (*pan_cb.pan_mfilt_ind_cb) (handle, indication, result, num_filters, p_filters); 728 #endif 729 730 return; 731 } 732 733