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