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 "bt_common.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 40tPAN_CB pan_cb; 41#endif 42 43#define UUID_CONSTANT_PART 12 44UINT8 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*******************************************************************************/ 58void 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*******************************************************************************/ 94void 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 /* Check for valid interactions between the three PAN profile roles */ 226 /* 227 * For reference, see Table 1 in PAN Profile v1.0 spec. 228 * Note: the remote is the initiator. 229 */ 230 BOOLEAN is_valid_interaction = FALSE; 231 switch (remote_uuid->uu.uuid16) { 232 case UUID_SERVCLASS_NAP: 233 case UUID_SERVCLASS_GN: 234 if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 235 is_valid_interaction = TRUE; 236 break; 237 case UUID_SERVCLASS_PANU: 238 is_valid_interaction = TRUE; 239 break; 240 } 241 /* 242 * Explicitly disable connections to the local PANU if the remote is 243 * not PANU. 244 */ 245 if ((local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) && 246 (remote_uuid->uu.uuid16 != UUID_SERVCLASS_PANU)) { 247 is_valid_interaction = FALSE; 248 } 249 if (!is_valid_interaction) { 250 PAN_TRACE_ERROR( 251 "PAN Connection failed because of invalid PAN profile roles " 252 "interaction: Remote UUID 0x%x Local UUID 0x%x", 253 remote_uuid->uu.uuid16, local_uuid->uu.uuid16); 254 BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID); 255 return; 256 } 257 258 /* Requested destination role is */ 259 if (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 260 req_role = PAN_ROLE_CLIENT; 261 else if (local_uuid->uu.uuid16 == UUID_SERVCLASS_GN) 262 req_role = PAN_ROLE_GN_SERVER; 263 else 264 req_role = PAN_ROLE_NAP_SERVER; 265 266 /* If the connection indication is for the existing connection 267 ** Check if the new destination role is acceptable 268 */ 269 pcb = pan_get_pcb_by_handle (handle); 270 if (pcb) 271 { 272 if (pan_cb.num_conns > 1 && local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU) 273 { 274 /* There are connections other than this one 275 ** so we cann't accept PANU role. Reject 276 */ 277 PAN_TRACE_ERROR ("Dst UUID should be either GN or NAP only because there are other connections"); 278 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 279 return; 280 } 281 282 /* If it is already in connected state check for bridging status */ 283 if (pcb->con_state == PAN_STATE_CONNECTED) 284 { 285 PAN_TRACE_EVENT ("PAN Role changing New Src 0x%x Dst 0x%x", 286 remote_uuid->uu.uuid16, local_uuid->uu.uuid16); 287 288 pcb->prv_src_uuid = pcb->src_uuid; 289 pcb->prv_dst_uuid = pcb->dst_uuid; 290 291 if (pcb->src_uuid == UUID_SERVCLASS_NAP && 292 local_uuid->uu.uuid16 != UUID_SERVCLASS_NAP) 293 { 294 /* Remove bridging */ 295 if (pan_cb.pan_bridge_req_cb) 296 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); 297 } 298 } 299 /* Set the latest active PAN role */ 300 pan_cb.active_role = req_role; 301 pcb->src_uuid = local_uuid->uu.uuid16; 302 pcb->dst_uuid = remote_uuid->uu.uuid16; 303 BNEP_ConnectResp (handle, BNEP_SUCCESS); 304 return; 305 } 306 else 307 { 308 /* If this a new connection and destination is PANU role and 309 ** we already have a connection then reject the request. 310 ** If we have a connection in PANU role then reject it 311 */ 312 if (pan_cb.num_conns && 313 (local_uuid->uu.uuid16 == UUID_SERVCLASS_PANU || 314 pan_cb.active_role == PAN_ROLE_CLIENT)) 315 { 316 PAN_TRACE_ERROR ("PAN already have a connection and can't be user"); 317 BNEP_ConnectResp (handle, BNEP_CONN_FAILED_DST_UUID); 318 return; 319 } 320 } 321 322 /* This is a new connection */ 323 PAN_TRACE_DEBUG ("New connection indication for handle %d", handle); 324 pcb = pan_allocate_pcb (p_bda, handle); 325 if (!pcb) 326 { 327 PAN_TRACE_ERROR ("PAN no control block for new connection"); 328 BNEP_ConnectResp (handle, BNEP_CONN_FAILED); 329 return; 330 } 331 332 PAN_TRACE_EVENT ("PAN connection destination UUID is 0x%x", local_uuid->uu.uuid16); 333 /* Set the latest active PAN role */ 334 pan_cb.active_role = req_role; 335 pcb->src_uuid = local_uuid->uu.uuid16; 336 pcb->dst_uuid = remote_uuid->uu.uuid16; 337 pcb->con_state = PAN_STATE_CONN_START; 338 pan_cb.num_conns++; 339 340 BNEP_ConnectResp (handle, BNEP_SUCCESS); 341 return; 342} 343 344 345/******************************************************************************* 346** 347** Function pan_connect_state_cb 348** 349** Description This function is registered with BNEP as connection state 350** change callback. BNEP will call this when the connection 351** is established successfully or terminated 352** 353** Parameters: handle - handle for the connection given in the connection 354** indication callback 355** rem_bda - remote device bd addr 356** result - indicates whether the connection is up or down 357** BNEP_SUCCESS if the connection is up 358** all other values indicates appropriate errors 359** is_role_change - flag to indicate that it is a role change 360** 361** Returns none 362** 363*******************************************************************************/ 364void pan_connect_state_cb (UINT16 handle, BD_ADDR rem_bda, tBNEP_RESULT result, BOOLEAN is_role_change) 365{ 366 tPAN_CONN *pcb; 367 UINT8 peer_role; 368 UNUSED(rem_bda); 369 370 PAN_TRACE_EVENT ("pan_connect_state_cb - for handle %d, result %d", handle, result); 371 pcb = pan_get_pcb_by_handle (handle); 372 if (!pcb) 373 { 374 PAN_TRACE_ERROR ("PAN State change indication for wrong handle %d", handle); 375 return; 376 } 377 378 /* If the connection is getting terminated remove bridging */ 379 if (result != BNEP_SUCCESS) 380 { 381 /* Inform the application that connection is down */ 382 if (pan_cb.pan_conn_state_cb) 383 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, result, is_role_change, PAN_ROLE_INACTIVE, PAN_ROLE_INACTIVE); 384 385 /* Check if this failure is for role change only */ 386 if (pcb->con_state != PAN_STATE_CONNECTED && 387 (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED)) 388 { 389 /* restore the original values */ 390 PAN_TRACE_EVENT ("restoring the connection state to active"); 391 pcb->con_state = PAN_STATE_CONNECTED; 392 pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED); 393 394 pcb->src_uuid = pcb->prv_src_uuid; 395 pcb->dst_uuid = pcb->prv_dst_uuid; 396 pan_cb.active_role = pan_cb.prv_active_role; 397 398 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb) 399 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE); 400 401 return; 402 } 403 404 if (pcb->con_state == PAN_STATE_CONNECTED) 405 { 406 /* If the connections destination role is NAP remove bridging */ 407 if ((pcb->src_uuid == UUID_SERVCLASS_NAP) && pan_cb.pan_bridge_req_cb) 408 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, FALSE); 409 } 410 411 pan_cb.num_conns--; 412 pan_release_pcb (pcb); 413 return; 414 } 415 416 /* Requested destination role is */ 417 if (pcb->src_uuid == UUID_SERVCLASS_PANU) 418 pan_cb.active_role = PAN_ROLE_CLIENT; 419 else if (pcb->src_uuid == UUID_SERVCLASS_GN) 420 pan_cb.active_role = PAN_ROLE_GN_SERVER; 421 else 422 pan_cb.active_role = PAN_ROLE_NAP_SERVER; 423 424 if (pcb->dst_uuid == UUID_SERVCLASS_PANU) 425 peer_role = PAN_ROLE_CLIENT; 426 else if (pcb->dst_uuid == UUID_SERVCLASS_GN) 427 peer_role = PAN_ROLE_GN_SERVER; 428 else 429 peer_role = PAN_ROLE_NAP_SERVER; 430 431 pcb->con_state = PAN_STATE_CONNECTED; 432 433 /* Inform the application that connection is down */ 434 if (pan_cb.pan_conn_state_cb) 435 (*pan_cb.pan_conn_state_cb) (pcb->handle, pcb->rem_bda, PAN_SUCCESS, is_role_change, pan_cb.active_role, peer_role); 436 437 /* Create bridge if the destination role is NAP */ 438 if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) 439 { 440 PAN_TRACE_EVENT ("PAN requesting for bridge"); 441 (*pan_cb.pan_bridge_req_cb) (pcb->rem_bda, TRUE); 442 } 443} 444 445 446/******************************************************************************* 447** 448** Function pan_data_ind_cb 449** 450** Description This function is registered with BNEP as data indication 451** callback. BNEP will call this when the peer sends any data 452** on this connection 453** 454** Parameters: handle - handle for the connection 455** src - source BD Addr 456** dst - destination BD Addr 457** protocol - Network protocol of the Eth packet 458** p_data - pointer to the data 459** len - length of the data 460** fw_ext_present - to indicate whether the data contains any 461** extension headers before the payload 462** 463** Returns none 464** 465*******************************************************************************/ 466void pan_data_ind_cb (UINT16 handle, 467 UINT8 *src, 468 UINT8 *dst, 469 UINT16 protocol, 470 UINT8 *p_data, 471 UINT16 len, 472 BOOLEAN ext) 473{ 474 tPAN_CONN *pcb; 475 UINT16 i; 476 BOOLEAN forward; 477 478 /* 479 ** Check the connection status 480 ** If the destination address is MAC broadcast send on all links 481 ** except on the one received 482 ** If the destination uuid is for NAP send to host system also 483 ** If the destination address is one of the devices connected 484 ** send the packet to over that link 485 ** If the destination address is unknown and destination uuid is NAP 486 ** send it to the host system 487 */ 488 489 PAN_TRACE_EVENT ("pan_data_ind_cb - for handle %d", handle); 490 pcb = pan_get_pcb_by_handle (handle); 491 if (!pcb) 492 { 493 PAN_TRACE_ERROR ("PAN Data indication for wrong handle %d", handle); 494 return; 495 } 496 497 if (pcb->con_state != PAN_STATE_CONNECTED) 498 { 499 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d", 500 pcb->con_state, handle); 501 return; 502 } 503 504 /* Check if it is broadcast packet */ 505 if (dst[0] & 0x01) 506 { 507 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x", 508 handle, pcb->src_uuid); 509 for (i=0; i<MAX_PAN_CONNS; i++) 510 { 511 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 512 pan_cb.pcb[i].handle != handle && 513 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 514 { 515 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 516 } 517 } 518 519 if (pan_cb.pan_data_ind_cb) 520 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, TRUE); 521 522 return; 523 } 524 525 /* Check if it is for any other PAN connection */ 526 for (i=0; i<MAX_PAN_CONNS; i++) 527 { 528 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 529 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 530 { 531 if (memcmp (pan_cb.pcb[i].rem_bda, dst, BD_ADDR_LEN) == 0) 532 { 533 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 534 return; 535 } 536 } 537 } 538 539 if (pcb->src_uuid == UUID_SERVCLASS_NAP) 540 forward = TRUE; 541 else 542 forward = FALSE; 543 544 /* Send it over the LAN or give it to host software */ 545 if (pan_cb.pan_data_ind_cb) 546 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 547 548 return; 549} 550 551 552/******************************************************************************* 553** 554** Function pan_data_buf_ind_cb 555** 556** Description This function is registered with BNEP as data buffer indication 557** callback. BNEP will call this when the peer sends any data 558** on this connection. PAN is responsible to release the buffer 559** 560** Parameters: handle - handle for the connection 561** src - source BD Addr 562** dst - destination BD Addr 563** protocol - Network protocol of the Eth packet 564** p_buf - pointer to the data buffer 565** ext - to indicate whether the data contains any 566** extension headers before the payload 567** 568** Returns none 569** 570*******************************************************************************/ 571void pan_data_buf_ind_cb (UINT16 handle, 572 UINT8 *src, 573 UINT8 *dst, 574 UINT16 protocol, 575 BT_HDR *p_buf, 576 BOOLEAN ext) 577{ 578 tPAN_CONN *pcb, *dst_pcb; 579 tBNEP_RESULT result; 580 UINT16 i, len; 581 UINT8 *p_data; 582 BOOLEAN forward = FALSE; 583 584 /* Check if the connection is in right state */ 585 pcb = pan_get_pcb_by_handle (handle); 586 if (!pcb) 587 { 588 PAN_TRACE_ERROR ("PAN Data buffer indication for wrong handle %d", handle); 589 osi_free(p_buf); 590 return; 591 } 592 593 if (pcb->con_state != PAN_STATE_CONNECTED) 594 { 595 PAN_TRACE_ERROR ("PAN Data indication in wrong state %d for handle %d", 596 pcb->con_state, handle); 597 osi_free(p_buf); 598 return; 599 } 600 601 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 602 len = p_buf->len; 603 604 PAN_TRACE_EVENT ("pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d", 605 handle, protocol, len, ext); 606 607 if (pcb->src_uuid == UUID_SERVCLASS_NAP) 608 forward = TRUE; 609 else 610 forward = FALSE; 611 612 /* Check if it is broadcast or multicast packet */ 613 if (pcb->src_uuid != UUID_SERVCLASS_PANU) 614 { 615 if (dst[0] & 0x01) 616 { 617 PAN_TRACE_DEBUG ("PAN received broadcast packet on handle %d, src uuid 0x%x", 618 handle, pcb->src_uuid); 619 for (i=0; i<MAX_PAN_CONNS; i++) 620 { 621 if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && 622 pan_cb.pcb[i].handle != handle && 623 pcb->src_uuid == pan_cb.pcb[i].src_uuid) 624 { 625 BNEP_Write (pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); 626 } 627 } 628 629 if (pan_cb.pan_data_buf_ind_cb) 630 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward); 631 else if (pan_cb.pan_data_ind_cb) 632 { 633 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 634 osi_free(p_buf); 635 } 636 637 return; 638 } 639 640 /* Check if it is for any other PAN connection */ 641 dst_pcb = pan_get_pcb_by_addr (dst); 642 if (dst_pcb) 643 { 644 PAN_TRACE_EVENT ("%s - destination PANU found on handle %d and sending data, len: %d", 645 __func__, dst_pcb->handle, len); 646 647 result = BNEP_Write (dst_pcb->handle, dst, p_data, len, protocol, src, ext); 648 if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD) 649 PAN_TRACE_ERROR ("Failed to write data for PAN connection handle %d", dst_pcb->handle); 650 osi_free(p_buf); 651 return; 652 } 653 } 654 655 /* Send it over the LAN or give it to host software */ 656 if (pan_cb.pan_data_buf_ind_cb) 657 (*pan_cb.pan_data_buf_ind_cb) (pcb->handle, src, dst, protocol, p_buf, ext, forward); 658 else if (pan_cb.pan_data_ind_cb) 659 { 660 (*pan_cb.pan_data_ind_cb) (pcb->handle, src, dst, protocol, p_data, len, ext, forward); 661 osi_free(p_buf); 662 } 663 else 664 osi_free(p_buf); 665 666 return; 667} 668 669/******************************************************************************* 670** 671** Function pan_proto_filt_ind_cb 672** 673** Description This function is registered with BNEP to receive tx data 674** flow status 675** 676** Parameters: handle - handle for the connection 677** event - flow status 678** 679** Returns none 680** 681*******************************************************************************/ 682void pan_tx_data_flow_cb (UINT16 handle, 683 tBNEP_RESULT event) 684{ 685 686 if (pan_cb.pan_tx_data_flow_cb) 687 (*pan_cb.pan_tx_data_flow_cb) (handle, event); 688 689 return; 690} 691 692/******************************************************************************* 693** 694** Function pan_proto_filt_ind_cb 695** 696** Description This function is registered with BNEP as proto filter indication 697** callback. BNEP will call this when the peer sends any protocol 698** filter set for the connection or to indicate the result of the 699** protocol filter set by the local device 700** 701** Parameters: handle - handle for the connection 702** indication - TRUE if this is indication 703** FALSE if it is called to give the result of local 704** device protocol filter set 705** result - This gives the result of the filter set operation 706** num_filters - number of filters set by the peer device 707** p_filters - pointer to the filters set by the peer device 708** 709** Returns none 710** 711*******************************************************************************/ 712void pan_proto_filt_ind_cb (UINT16 handle, 713 BOOLEAN indication, 714 tBNEP_RESULT result, 715 UINT16 num_filters, 716 UINT8 *p_filters) 717{ 718 PAN_TRACE_EVENT ("pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, num %d", 719 handle, indication, result, num_filters); 720 721 if (pan_cb.pan_pfilt_ind_cb) 722 (*pan_cb.pan_pfilt_ind_cb) (handle, indication, result, num_filters, p_filters); 723} 724 725 726/******************************************************************************* 727** 728** Function pan_mcast_filt_ind_cb 729** 730** Description This function is registered with BNEP as mcast filter indication 731** callback. BNEP will call this when the peer sends any multicast 732** filter set for the connection or to indicate the result of the 733** multicast filter set by the local device 734** 735** Parameters: handle - handle for the connection 736** indication - TRUE if this is indication 737** FALSE if it is called to give the result of local 738** device multicast filter set 739** result - This gives the result of the filter set operation 740** num_filters - number of filters set by the peer device 741** p_filters - pointer to the filters set by the peer device 742** 743** Returns none 744** 745*******************************************************************************/ 746void pan_mcast_filt_ind_cb (UINT16 handle, 747 BOOLEAN indication, 748 tBNEP_RESULT result, 749 UINT16 num_filters, 750 UINT8 *p_filters) 751{ 752 PAN_TRACE_EVENT ("pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, num %d", 753 handle, indication, result, num_filters); 754 755 if (pan_cb.pan_mfilt_ind_cb) 756 (*pan_cb.pan_mfilt_ind_cb) (handle, indication, result, num_filters, p_filters); 757} 758