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 (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_ERROR ("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_ERROR ("PAN Connection failed because of wrong local UUID "); 178 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 179 return; 180 } 181 182 PAN_TRACE_EVENT ("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_ERROR ("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 192 /* Check if the source UUID is a valid one */ 193 if (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU && 194 remote_uuid->uu.uuid16 != UUID_SERVCLASS_NAP && 195 remote_uuid->uu.uuid16 != UUID_SERVCLASS_GN) 196 { 197 PAN_TRACE_ERROR ("Src UUID 0x%x is not valid", remote_uuid->uu.uuid16); 198 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_SRC_UUID); 199 return; 200 } 201 202 /* Check if the destination UUID is a valid one */ 203 if (local_uuid->uu.uuid16 != UUID_SERVCLASS_PANU && 204 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP && 205 local_uuid->uu.uuid16 != UUID_SERVCLASS_GN) 206 { 207 PAN_TRACE_ERROR ("Dst UUID 0x%x is not valid", remote_uuid->uu.uuid16); 208 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 209 return; 210 } 211 212 /* Check if currently we support the destination role requested */ 213 if (((!(pan_cb.role & UUID_SERVCLASS_PANU)) 214 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) || 215 ((!(pan_cb.role & UUID_SERVCLASS_GN)) 216 && local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) || 217 ((!(pan_cb.role & UUID_SERVCLASS_NAP)) 218 && local_uuid->uu.uuid16 == UUID_SERVCLASS_NAP)) 219 { 220 PAN_TRACE_ERROR ("PAN Connection failed because of unsupported destination UUID 0x%x", local_uuid->uu.uuid16); 221 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 222 return; 223 } 224 225 /* Requested destination role is */ 226 if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 227 req_role = PAN_ROLE_CLIENT; 228 else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) 229 req_role = PAN_ROLE_GN_SERVER; 230 else 231 req_role = PAN_ROLE_NAP_SERVER; 232 233 /* If the connection indication is for the existing connection 234 ** Check if the new destination role is acceptable 235 */ 236 pcb = pan_get_pcb_by_handle (handle); 237 if (pcb) 238 { 239 if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 240 { 241 /* There are connections other than this one 242 ** so we cann't accept PANU role. Reject 243 */ 244 PAN_TRACE_ERROR ("Dst UUID should be either GN or NAP only because there are other connections"); 245 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 246 return; 247 } 248 249 /* If it is already in connected state check for bridging status */ 250 if (pcb->con_state == PAN_STATE_CONNECTED) 251 { 252 PAN_TRACE_EVENT ("PAN Role changing New Src 0x%x Dst 0x%x", 253 remote_uuid->uu.uuid16, local_uuid->uu.uuid16); 254 255 pcb->prv_src_uuid = pcb->src_uuid; 256 pcb->prv_dst_uuid = pcb->dst_uuid; 257 258 if (pcb->src_uuid == UUID_SERVCLASS_NAP && 259 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP) 260 { 261 /* Remove bridging */ 262 if (pan_cb.pan_bridge_req_cb) 263 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); 264 } 265 } 266 /* Set the latest active PAN role */ 267 pan_cb.active_role = req_role; 268 pcb->src_uuid = local_uuid->uu.uuid16; 269 pcb->dst_uuid = remote_uuid->uu.uuid16; 270 BNEP_ConnectResp (handle, BNEP_SUCCESS); 271 return; 272 } 273 else 274 { 275 /* If this a new connection and destination is PANU role and 276 ** we already have a connection then reject the request. 277 ** If we have a connection in PANU role then reject it 278 */ 279 if (pan_cb.num_conns && 280 (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU || 281 pan_cb.active_role == PAN_ROLE_CLIENT)) 282 { 283 PAN_TRACE_ERROR ("PAN already have a connection and can't be user"); 284 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 285 return; 286 } 287 } 288 289 /* This is a new connection */ 290 PAN_TRACE_DEBUG ("New connection indication for handle %d", handle); 291 pcb = pan_allocate_pcb (p_bda, handle); 292 if (!pcb) 293 { 294 PAN_TRACE_ERROR ("PAN no control block for new connection"); 295 BNEP_ConnectResp (handle, BNEP_CONN_FAILED); 296 return; 297 } 298 299 PAN_TRACE_EVENT ("PAN connection destination UUID is 0x%x", local_uuid->uu.uuid16); 300 /* Set the latest active PAN role */ 301 pan_cb.active_role = req_role; 302 pcb->src_uuid = local_uuid->uu.uuid16; 303 pcb->dst_uuid = remote_uuid->uu.uuid16; 304 pcb->con_state = PAN_STATE_CONN_START; 305 pan_cb.num_conns++; 306 307 BNEP_ConnectResp (handle, BNEP_SUCCESS); 308 return; 309 } 310 311 312 /******************************************************************************* 313 ** 314 ** Function pan_connect_state_cb 315 ** 316 ** Description This function is registered with BNEP as connection state 317 ** change callback. BNEP will call this when the connection 318 ** is established successfully or terminated 319 ** 320 ** Parameters: handle - handle for the connection given in the connection 321 ** indication callback 322 ** rem_bda - remote device bd addr 323 ** result - indicates whether the connection is up or down 324 ** BNEP_SUCCESS if the connection is up 325 ** all other values indicates appropriate errors 326 ** is_role_change - flag to indicate that it is a role change 327 ** 328 ** Returns none 329 ** 330 *******************************************************************************/ 331 void pan_connect_state_cb (UINT16 handle, BD_ADDR rem_bda, tBNEP_RESULT result, BOOLEAN is_role_change) 332 { 333 tPAN_CONN *pcb; 334 UINT8 peer_role; 335 UNUSED(rem_bda); 336 337 PAN_TRACE_EVENT ("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_ERROR ("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_EVENT ("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_EVENT ("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_EVENT ("pan_data_ind_cb - for handle %d", handle); 457 pcb = pan_get_pcb_by_handle (handle); 458 if (!pcb) 459 { 460 PAN_TRACE_ERROR ("PAN Data indication for wrong handle %d", handle); 461 return; 462 } 463 464 if (pcb->con_state != PAN_STATE_CONNECTED) 465 { 466 PAN_TRACE_ERROR ("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_DEBUG ("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_ERROR ("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_ERROR ("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_EVENT ("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_DEBUG ("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_EVENT ("%s - destination PANU found on handle %d and sending data, len: %d", 612 __func__, dst_pcb->handle, len); 613 614 result = BNEP_Write (dst_pcb->handle, dst, p_data, len, 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 GKI_freebuf (p_buf); 618 return; 619 } 620 } 621 622 /* Send it over the LAN or give it to host software */ 623 if (pan_cb.pan_data_buf_ind_cb) 624 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward); 625 else if (pan_cb.pan_data_ind_cb) 626 { 627 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 628 GKI_freebuf (p_buf); 629 } 630 else 631 GKI_freebuf (p_buf); 632 633 return; 634 } 635 636 /******************************************************************************* 637 ** 638 ** Function pan_proto_filt_ind_cb 639 ** 640 ** Description This function is registered with BNEP to receive tx data 641 ** flow status 642 ** 643 ** Parameters: handle - handle for the connection 644 ** event - flow status 645 ** 646 ** Returns none 647 ** 648 *******************************************************************************/ 649 void pan_tx_data_flow_cb (UINT16 handle, 650 tBNEP_RESULT event) 651 { 652 653 if (pan_cb.pan_tx_data_flow_cb) 654 (*pan_cb.pan_tx_data_flow_cb) (handle, event); 655 656 return; 657 } 658 659 /******************************************************************************* 660 ** 661 ** Function pan_proto_filt_ind_cb 662 ** 663 ** Description This function is registered with BNEP as proto filter indication 664 ** callback. BNEP will call this when the peer sends any protocol 665 ** filter set for the connection or to indicate the result of the 666 ** protocol filter set by the local device 667 ** 668 ** Parameters: handle - handle for the connection 669 ** indication - TRUE if this is indication 670 ** FALSE if it is called to give the result of local 671 ** device protocol filter set 672 ** result - This gives the result of the filter set operation 673 ** num_filters - number of filters set by the peer device 674 ** p_filters - pointer to the filters set by the peer device 675 ** 676 ** Returns none 677 ** 678 *******************************************************************************/ 679 void pan_proto_filt_ind_cb (UINT16 handle, 680 BOOLEAN indication, 681 tBNEP_RESULT result, 682 UINT16 num_filters, 683 UINT8 *p_filters) 684 { 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 } 691 692 693 /******************************************************************************* 694 ** 695 ** Function pan_mcast_filt_ind_cb 696 ** 697 ** Description This function is registered with BNEP as mcast filter indication 698 ** callback. BNEP will call this when the peer sends any multicast 699 ** filter set for the connection or to indicate the result of the 700 ** multicast filter set by the local device 701 ** 702 ** Parameters: handle - handle for the connection 703 ** indication - TRUE if this is indication 704 ** FALSE if it is called to give the result of local 705 ** device multicast filter set 706 ** result - This gives the result of the filter set operation 707 ** num_filters - number of filters set by the peer device 708 ** p_filters - pointer to the filters set by the peer device 709 ** 710 ** Returns none 711 ** 712 *******************************************************************************/ 713 void pan_mcast_filt_ind_cb (UINT16 handle, 714 BOOLEAN indication, 715 tBNEP_RESULT result, 716 UINT16 num_filters, 717 UINT8 *p_filters) 718 { 719 PAN_TRACE_EVENT ("pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, num %d", 720 handle, indication, result, num_filters); 721 722 if (pan_cb.pan_mfilt_ind_cb) 723 (*pan_cb.pan_mfilt_ind_cb) (handle, indication, result, num_filters, p_filters); 724 } 725