1/****************************************************************************** 2 * 3 * Copyright (C) 2001-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 the BNEP API code 22 * 23 ******************************************************************************/ 24 25#include <string.h> 26#include "bnep_api.h" 27#include "bnep_int.h" 28 29/******************************************************************************* 30** 31** Function BNEP_Init 32** 33** Description This function initializes the BNEP unit. It should be called 34** before accessing any other APIs to initialize the control block 35** 36** Returns void 37** 38*******************************************************************************/ 39void BNEP_Init (void) 40{ 41 memset (&bnep_cb, 0, sizeof (tBNEP_CB)); 42 43#if defined(BNEP_INITIAL_TRACE_LEVEL) 44 bnep_cb.trace_level = BNEP_INITIAL_TRACE_LEVEL; 45#else 46 bnep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 47#endif 48 49 /* Start a timer to read our BD address */ 50 btu_start_timer (&bnep_cb.bnep_tle, BTU_TTYPE_BNEP, 2); 51} 52 53 54/******************************************************************************* 55** 56** Function BNEP_Register 57** 58** Description This function is called by the upper layer to register 59** its callbacks with BNEP 60** 61** Parameters: p_reg_info - contains all callback function pointers 62** 63** 64** Returns BNEP_SUCCESS if registered successfully 65** BNEP_FAILURE if connection state callback is missing 66** 67*******************************************************************************/ 68tBNEP_RESULT BNEP_Register (tBNEP_REGISTER *p_reg_info) 69{ 70 /* There should be connection state call back registered */ 71 if ((!p_reg_info) || (!(p_reg_info->p_conn_state_cb))) 72 return BNEP_SECURITY_FAIL; 73 74 bnep_cb.p_conn_ind_cb = p_reg_info->p_conn_ind_cb; 75 bnep_cb.p_conn_state_cb = p_reg_info->p_conn_state_cb; 76 bnep_cb.p_data_ind_cb = p_reg_info->p_data_ind_cb; 77 bnep_cb.p_data_buf_cb = p_reg_info->p_data_buf_cb; 78 bnep_cb.p_filter_ind_cb = p_reg_info->p_filter_ind_cb; 79 bnep_cb.p_mfilter_ind_cb = p_reg_info->p_mfilter_ind_cb; 80 bnep_cb.p_tx_data_flow_cb = p_reg_info->p_tx_data_flow_cb; 81 82 if (bnep_register_with_l2cap ()) 83 return BNEP_SECURITY_FAIL; 84 85 bnep_cb.profile_registered = TRUE; 86 return BNEP_SUCCESS; 87} 88 89 90/******************************************************************************* 91** 92** Function BNEP_Deregister 93** 94** Description This function is called by the upper layer to de-register 95** its callbacks. 96** 97** Parameters: void 98** 99** 100** Returns void 101** 102*******************************************************************************/ 103void BNEP_Deregister (void) 104{ 105 /* Clear all the call backs registered */ 106 bnep_cb.p_conn_ind_cb = NULL; 107 bnep_cb.p_conn_state_cb = NULL; 108 bnep_cb.p_data_ind_cb = NULL; 109 bnep_cb.p_data_buf_cb = NULL; 110 bnep_cb.p_filter_ind_cb = NULL; 111 bnep_cb.p_mfilter_ind_cb = NULL; 112 113 bnep_cb.profile_registered = FALSE; 114 L2CA_Deregister (BT_PSM_BNEP); 115} 116 117 118/******************************************************************************* 119** 120** Function BNEP_Connect 121** 122** Description This function creates a BNEP connection to a remote 123** device. 124** 125** Parameters: p_rem_addr - BD_ADDR of the peer 126** src_uuid - source uuid for the connection 127** dst_uuid - destination uuid for the connection 128** p_handle - pointer to return the handle for the connection 129** 130** Returns BNEP_SUCCESS if connection started 131** BNEP_NO_RESOURCES if no resources 132** 133*******************************************************************************/ 134tBNEP_RESULT BNEP_Connect (BD_ADDR p_rem_bda, 135 tBT_UUID *src_uuid, 136 tBT_UUID *dst_uuid, 137 UINT16 *p_handle) 138{ 139 UINT16 cid; 140 tBNEP_CONN *p_bcb = bnepu_find_bcb_by_bd_addr (p_rem_bda); 141 142 BNEP_TRACE_API ("BNEP_Connect() BDA: %02x-%02x-%02x-%02x-%02x-%02x", 143 p_rem_bda[0], p_rem_bda[1], p_rem_bda[2], 144 p_rem_bda[3], p_rem_bda[4], p_rem_bda[5]); 145 146 if (!bnep_cb.profile_registered) 147 return BNEP_WRONG_STATE; 148 149 /* Both source and destination UUID lengths should be same */ 150 if (src_uuid->len != dst_uuid->len) 151 return BNEP_CONN_FAILED_UUID_SIZE; 152 153 if (!p_bcb) 154 { 155 if ((p_bcb = bnepu_allocate_bcb (p_rem_bda)) == NULL) 156 return (BNEP_NO_RESOURCES); 157 } 158 else if (p_bcb->con_state != BNEP_STATE_CONNECTED) 159 return BNEP_WRONG_STATE; 160 else 161 { 162 /* Backup current UUID values to restore if role change fails */ 163 memcpy ((UINT8 *)&(p_bcb->prv_src_uuid), (UINT8 *)&(p_bcb->src_uuid), sizeof (tBT_UUID)); 164 memcpy ((UINT8 *)&(p_bcb->prv_dst_uuid), (UINT8 *)&(p_bcb->dst_uuid), sizeof (tBT_UUID)); 165 } 166 167 /* We are the originator of this connection */ 168 p_bcb->con_flags |= BNEP_FLAGS_IS_ORIG; 169 170 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)src_uuid, sizeof (tBT_UUID)); 171 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)dst_uuid, sizeof (tBT_UUID)); 172 173 if (p_bcb->con_state == BNEP_STATE_CONNECTED) 174 { 175 /* Transition to the next appropriate state, waiting for connection confirm. */ 176 p_bcb->con_state = BNEP_STATE_SEC_CHECKING; 177 178 BNEP_TRACE_API ("BNEP initiating security procedures for src uuid 0x%x", 179 p_bcb->src_uuid.uu.uuid16); 180 181#if (defined (BNEP_DO_AUTH_FOR_ROLE_SWITCH) && BNEP_DO_AUTH_FOR_ROLE_SWITCH == TRUE) 182 btm_sec_mx_access_request (p_bcb->rem_bda, BT_PSM_BNEP, TRUE, 183 BTM_SEC_PROTO_BNEP, 184 bnep_get_uuid32(src_uuid), 185 &bnep_sec_check_complete, p_bcb); 186#else 187 bnep_sec_check_complete (p_bcb->rem_bda, p_bcb, BTM_SUCCESS); 188#endif 189 190 } 191 else 192 { 193 /* Transition to the next appropriate state, waiting for connection confirm. */ 194 p_bcb->con_state = BNEP_STATE_CONN_START; 195 196 if ((cid = L2CA_ConnectReq (BT_PSM_BNEP, p_bcb->rem_bda)) != 0) 197 { 198 p_bcb->l2cap_cid = cid; 199 200 } 201 else 202 { 203 BNEP_TRACE_ERROR ("BNEP - Originate failed"); 204 if (bnep_cb.p_conn_state_cb) 205 (*bnep_cb.p_conn_state_cb) (p_bcb->handle, p_bcb->rem_bda, BNEP_CONN_FAILED, FALSE); 206 bnepu_release_bcb (p_bcb); 207 return BNEP_CONN_FAILED; 208 } 209 210 /* Start timer waiting for connect */ 211 btu_start_timer (&p_bcb->conn_tle, BTU_TTYPE_BNEP, BNEP_CONN_TIMEOUT); 212 } 213 214 *p_handle = p_bcb->handle; 215 return (BNEP_SUCCESS); 216} 217 218 219/******************************************************************************* 220** 221** Function BNEP_ConnectResp 222** 223** Description This function is called in responce to connection indication 224** 225** 226** Parameters: handle - handle given in the connection indication 227** resp - responce for the connection indication 228** 229** Returns BNEP_SUCCESS if connection started 230** BNEP_WRONG_HANDLE if the connection is not found 231** BNEP_WRONG_STATE if the responce is not expected 232** 233*******************************************************************************/ 234tBNEP_RESULT BNEP_ConnectResp (UINT16 handle, tBNEP_RESULT resp) 235{ 236 tBNEP_CONN *p_bcb; 237 UINT16 resp_code = BNEP_SETUP_CONN_OK; 238 239 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 240 return (BNEP_WRONG_HANDLE); 241 242 p_bcb = &(bnep_cb.bcb[handle - 1]); 243 244 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP || 245 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))) 246 return (BNEP_WRONG_STATE); 247 248 BNEP_TRACE_API ("BNEP_ConnectResp() for handle %d, responce %d", handle, resp); 249 250 /* Form appropriate responce based on profile responce */ 251 if (resp == BNEP_CONN_FAILED_SRC_UUID) resp_code = BNEP_SETUP_INVALID_SRC_UUID; 252 else if (resp == BNEP_CONN_FAILED_DST_UUID) resp_code = BNEP_SETUP_INVALID_DEST_UUID; 253 else if (resp == BNEP_CONN_FAILED_UUID_SIZE) resp_code = BNEP_SETUP_INVALID_UUID_SIZE; 254 else if (resp == BNEP_SUCCESS) resp_code = BNEP_SETUP_CONN_OK; 255 else resp_code = BNEP_SETUP_CONN_NOT_ALLOWED; 256 257 bnep_send_conn_responce (p_bcb, resp_code); 258 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 259 260 if (resp == BNEP_SUCCESS) 261 bnep_connected (p_bcb); 262 else if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 263 { 264 /* Restore the original parameters */ 265 p_bcb->con_state = BNEP_STATE_CONNECTED; 266 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 267 268 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID)); 269 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID)); 270 } 271 272 /* Process remaining part of the setup message (extension headers) */ 273 if (p_bcb->p_pending_data) 274 { 275 UINT8 extension_present = TRUE, *p, ext_type; 276 UINT16 rem_len; 277 278 rem_len = p_bcb->p_pending_data->len; 279 p = (UINT8 *)(p_bcb->p_pending_data + 1) + p_bcb->p_pending_data->offset; 280 while (extension_present && p && rem_len) 281 { 282 ext_type = *p++; 283 extension_present = ext_type >> 7; 284 ext_type &= 0x7F; 285 286 /* if unknown extension present stop processing */ 287 if (ext_type) 288 break; 289 290 p = bnep_process_control_packet (p_bcb, p, &rem_len, TRUE); 291 } 292 293 GKI_freebuf (p_bcb->p_pending_data); 294 p_bcb->p_pending_data = NULL; 295 } 296 return (BNEP_SUCCESS); 297} 298 299 300/******************************************************************************* 301** 302** Function BNEP_Disconnect 303** 304** Description This function is called to close the specified connection. 305** 306** Parameters: handle - handle of the connection 307** 308** Returns BNEP_SUCCESS if connection is disconnected 309** BNEP_WRONG_HANDLE if no connection is not found 310** 311*******************************************************************************/ 312tBNEP_RESULT BNEP_Disconnect (UINT16 handle) 313{ 314 tBNEP_CONN *p_bcb; 315 316 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 317 return (BNEP_WRONG_HANDLE); 318 319 p_bcb = &(bnep_cb.bcb[handle - 1]); 320 321 if (p_bcb->con_state == BNEP_STATE_IDLE) 322 return (BNEP_WRONG_HANDLE); 323 324 BNEP_TRACE_API ("BNEP_Disconnect() for handle %d", handle); 325 326 L2CA_DisconnectReq (p_bcb->l2cap_cid); 327 328 bnepu_release_bcb (p_bcb); 329 330 return (BNEP_SUCCESS); 331} 332 333 334/******************************************************************************* 335** 336** Function BNEP_WriteBuf 337** 338** Description This function sends data in a GKI buffer on BNEP connection 339** 340** Parameters: handle - handle of the connection to write 341** p_dest_addr - BD_ADDR/Ethernet addr of the destination 342** p_buf - pointer to address of buffer with data 343** protocol - protocol type of the packet 344** p_src_addr - (optional) BD_ADDR/ethernet address of the source 345** (should be NULL if it is local BD Addr) 346** fw_ext_present - forwarded extensions present 347** 348** Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 349** BNEP_MTU_EXCEDED - If the data length is greater than MTU 350** BNEP_IGNORE_CMD - If the packet is filtered out 351** BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 352** BNEP_SUCCESS - If written successfully 353** 354*******************************************************************************/ 355tBNEP_RESULT BNEP_WriteBuf (UINT16 handle, 356 UINT8 *p_dest_addr, 357 BT_HDR *p_buf, 358 UINT16 protocol, 359 UINT8 *p_src_addr, 360 BOOLEAN fw_ext_present) 361{ 362 tBNEP_CONN *p_bcb; 363 UINT8 *p_data; 364 365 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 366 { 367 GKI_freebuf (p_buf); 368 return (BNEP_WRONG_HANDLE); 369 } 370 371 p_bcb = &(bnep_cb.bcb[handle - 1]); 372 /* Check MTU size */ 373 if (p_buf->len > BNEP_MTU_SIZE) 374 { 375 BNEP_TRACE_ERROR ("BNEP_Write() length %d exceeded MTU %d", p_buf->len, BNEP_MTU_SIZE); 376 GKI_freebuf (p_buf); 377 return (BNEP_MTU_EXCEDED); 378 } 379 380 /* Check if the packet should be filtered out */ 381 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 382 if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, p_data) != BNEP_SUCCESS) 383 { 384 /* 385 ** If packet is filtered and ext headers are present 386 ** drop the data and forward the ext headers 387 */ 388 if (fw_ext_present) 389 { 390 UINT8 ext, length; 391 UINT16 org_len, new_len; 392 /* parse the extension headers and findout the new packet len */ 393 org_len = p_buf->len; 394 new_len = 0; 395 do { 396 397 ext = *p_data++; 398 length = *p_data++; 399 p_data += length; 400 401 new_len += (length + 2); 402 403 if (new_len > org_len) 404 { 405 GKI_freebuf (p_buf); 406 return BNEP_IGNORE_CMD; 407 } 408 409 } while (ext & 0x80); 410 411 if (protocol != BNEP_802_1_P_PROTOCOL) 412 protocol = 0; 413 else 414 { 415 new_len += 4; 416 p_data[2] = 0; 417 p_data[3] = 0; 418 } 419 p_buf->len = new_len; 420 } 421 else 422 { 423 GKI_freebuf (p_buf); 424 return BNEP_IGNORE_CMD; 425 } 426 } 427 428 /* Check transmit queue */ 429 if (GKI_queue_length(&p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) 430 { 431 GKI_freebuf (p_buf); 432 return (BNEP_Q_SIZE_EXCEEDED); 433 } 434 435 /* Build the BNEP header */ 436 bnepu_build_bnep_hdr (p_bcb, p_buf, protocol, p_src_addr, p_dest_addr, fw_ext_present); 437 438 /* Send the data or queue it up */ 439 bnepu_check_send_packet (p_bcb, p_buf); 440 441 return (BNEP_SUCCESS); 442} 443 444 445/******************************************************************************* 446** 447** Function BNEP_Write 448** 449** Description This function sends data over a BNEP connection 450** 451** Parameters: handle - handle of the connection to write 452** p_dest_addr - BD_ADDR/Ethernet addr of the destination 453** p_data - pointer to data start 454** protocol - protocol type of the packet 455** p_src_addr - (optional) BD_ADDR/ethernet address of the source 456** (should be NULL if it is local BD Addr) 457** fw_ext_present - forwarded extensions present 458** 459** Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 460** BNEP_MTU_EXCEDED - If the data length is greater than MTU 461** BNEP_IGNORE_CMD - If the packet is filtered out 462** BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 463** BNEP_NO_RESOURCES - If not able to allocate a buffer 464** BNEP_SUCCESS - If written successfully 465** 466*******************************************************************************/ 467tBNEP_RESULT BNEP_Write (UINT16 handle, 468 UINT8 *p_dest_addr, 469 UINT8 *p_data, 470 UINT16 len, 471 UINT16 protocol, 472 UINT8 *p_src_addr, 473 BOOLEAN fw_ext_present) 474{ 475 BT_HDR *p_buf; 476 tBNEP_CONN *p_bcb; 477 UINT8 *p; 478 479 /* Check MTU size. Consider the possibility of having extension headers */ 480 if (len > BNEP_MTU_SIZE) 481 { 482 BNEP_TRACE_ERROR ("BNEP_Write() length %d exceeded MTU %d", len, BNEP_MTU_SIZE); 483 return (BNEP_MTU_EXCEDED); 484 } 485 486 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 487 return (BNEP_WRONG_HANDLE); 488 489 p_bcb = &(bnep_cb.bcb[handle - 1]); 490 491 /* Check if the packet should be filtered out */ 492 if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, p_data) != BNEP_SUCCESS) 493 { 494 /* 495 ** If packet is filtered and ext headers are present 496 ** drop the data and forward the ext headers 497 */ 498 if (fw_ext_present) 499 { 500 UINT8 ext, length; 501 UINT16 org_len, new_len; 502 /* parse the extension headers and findout the new packet len */ 503 org_len = len; 504 new_len = 0; 505 p = p_data; 506 do { 507 508 ext = *p_data++; 509 length = *p_data++; 510 p_data += length; 511 512 new_len += (length + 2); 513 514 if (new_len > org_len) 515 return BNEP_IGNORE_CMD; 516 517 } while (ext & 0x80); 518 519 if (protocol != BNEP_802_1_P_PROTOCOL) 520 protocol = 0; 521 else 522 { 523 new_len += 4; 524 p_data[2] = 0; 525 p_data[3] = 0; 526 } 527 len = new_len; 528 p_data = p; 529 } 530 else 531 return BNEP_IGNORE_CMD; 532 } 533 534 /* Check transmit queue */ 535 if (GKI_queue_length(&p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) 536 return (BNEP_Q_SIZE_EXCEEDED); 537 538 /* Get a buffer to copy teh data into */ 539 if ((p_buf = (BT_HDR *)GKI_getpoolbuf (BNEP_POOL_ID)) == NULL) 540 { 541 BNEP_TRACE_ERROR ("BNEP_Write() not able to get buffer"); 542 return (BNEP_NO_RESOURCES); 543 } 544 545 p_buf->len = len; 546 p_buf->offset = BNEP_MINIMUM_OFFSET; 547 p = (UINT8 *)(p_buf + 1) + BNEP_MINIMUM_OFFSET; 548 549 memcpy (p, p_data, len); 550 551 /* Build the BNEP header */ 552 bnepu_build_bnep_hdr (p_bcb, p_buf, protocol, p_src_addr, p_dest_addr, fw_ext_present); 553 554 /* Send the data or queue it up */ 555 bnepu_check_send_packet (p_bcb, p_buf); 556 557 return (BNEP_SUCCESS); 558} 559 560 561/******************************************************************************* 562** 563** Function BNEP_SetProtocolFilters 564** 565** Description This function sets the protocol filters on peer device 566** 567** Parameters: handle - Handle for the connection 568** num_filters - total number of filter ranges 569** p_start_array - Array of beginings of all protocol ranges 570** p_end_array - Array of ends of all protocol ranges 571** 572** Returns BNEP_WRONG_HANDLE - if the connection handle is not valid 573** BNEP_SET_FILTER_FAIL - if the connection is in wrong state 574** BNEP_TOO_MANY_FILTERS - if too many filters 575** BNEP_SUCCESS - if request sent successfully 576** 577*******************************************************************************/ 578tBNEP_RESULT BNEP_SetProtocolFilters (UINT16 handle, 579 UINT16 num_filters, 580 UINT16 *p_start_array, 581 UINT16 *p_end_array) 582{ 583 UINT16 xx; 584 tBNEP_CONN *p_bcb; 585 586 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 587 return (BNEP_WRONG_HANDLE); 588 589 p_bcb = &(bnep_cb.bcb[handle - 1]); 590 591 /* Check the connection state */ 592 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 593 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 594 return (BNEP_WRONG_STATE); 595 596 /* Validate the parameters */ 597 if (num_filters && (!p_start_array || !p_end_array)) 598 return (BNEP_SET_FILTER_FAIL); 599 600 if (num_filters > BNEP_MAX_PROT_FILTERS) 601 return (BNEP_TOO_MANY_FILTERS); 602 603 /* Fill the filter values in connnection block */ 604 for (xx = 0; xx < num_filters; xx++) 605 { 606 p_bcb->sent_prot_filter_start[xx] = *p_start_array++; 607 p_bcb->sent_prot_filter_end[xx] = *p_end_array++; 608 } 609 610 p_bcb->sent_num_filters = num_filters; 611 612 bnepu_send_peer_our_filters (p_bcb); 613 614 return (BNEP_SUCCESS); 615} 616 617 618/******************************************************************************* 619** 620** Function BNEP_SetMulticastFilters 621** 622** Description This function sets the filters for multicast addresses for BNEP. 623** 624** Parameters: handle - Handle for the connection 625** num_filters - total number of filter ranges 626** p_start_array - Pointer to sequence of beginings of all 627** multicast address ranges 628** p_end_array - Pointer to sequence of ends of all 629** multicast address ranges 630** 631** Returns BNEP_WRONG_HANDLE - if the connection handle is not valid 632** BNEP_SET_FILTER_FAIL - if the connection is in wrong state 633** BNEP_TOO_MANY_FILTERS - if too many filters 634** BNEP_SUCCESS - if request sent successfully 635** 636*******************************************************************************/ 637tBNEP_RESULT BNEP_SetMulticastFilters (UINT16 handle, 638 UINT16 num_filters, 639 UINT8 *p_start_array, 640 UINT8 *p_end_array) 641{ 642 UINT16 xx; 643 tBNEP_CONN *p_bcb; 644 645 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 646 return (BNEP_WRONG_HANDLE); 647 648 p_bcb = &(bnep_cb.bcb[handle - 1]); 649 650 /* Check the connection state */ 651 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 652 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 653 return (BNEP_WRONG_STATE); 654 655 /* Validate the parameters */ 656 if (num_filters && (!p_start_array || !p_end_array)) 657 return (BNEP_SET_FILTER_FAIL); 658 659 if (num_filters > BNEP_MAX_MULTI_FILTERS) 660 return (BNEP_TOO_MANY_FILTERS); 661 662 /* Fill the multicast filter values in connnection block */ 663 for (xx = 0; xx < num_filters; xx++) 664 { 665 memcpy (p_bcb->sent_mcast_filter_start[xx], p_start_array, BD_ADDR_LEN); 666 memcpy (p_bcb->sent_mcast_filter_end[xx], p_end_array, BD_ADDR_LEN); 667 668 p_start_array += BD_ADDR_LEN; 669 p_end_array += BD_ADDR_LEN; 670 } 671 672 p_bcb->sent_mcast_filters = num_filters; 673 674 bnepu_send_peer_our_multi_filters (p_bcb); 675 676 return (BNEP_SUCCESS); 677} 678 679/******************************************************************************* 680** 681** Function BNEP_SetTraceLevel 682** 683** Description This function sets the trace level for BNEP. If called with 684** a value of 0xFF, it simply reads the current trace level. 685** 686** Returns the new (current) trace level 687** 688*******************************************************************************/ 689UINT8 BNEP_SetTraceLevel (UINT8 new_level) 690{ 691 if (new_level != 0xFF) 692 bnep_cb.trace_level = new_level; 693 694 return (bnep_cb.trace_level); 695} 696 697 698/******************************************************************************* 699** 700** Function BNEP_GetStatus 701** 702** Description This function gets the status information for BNEP connection 703** 704** Returns BNEP_SUCCESS - if the status is available 705** BNEP_NO_RESOURCES - if no structure is passed for output 706** BNEP_WRONG_HANDLE - if the handle is invalid 707** BNEP_WRONG_STATE - if not in connected state 708** 709*******************************************************************************/ 710tBNEP_RESULT BNEP_GetStatus (UINT16 handle, tBNEP_STATUS *p_status) 711{ 712#if (defined (BNEP_SUPPORTS_STATUS_API) && BNEP_SUPPORTS_STATUS_API == TRUE) 713 tBNEP_CONN *p_bcb; 714 715 if (!p_status) 716 return BNEP_NO_RESOURCES; 717 718 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 719 return (BNEP_WRONG_HANDLE); 720 721 p_bcb = &(bnep_cb.bcb[handle - 1]); 722 723 memset (p_status, 0, sizeof (tBNEP_STATUS)); 724 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 725 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 726 return BNEP_WRONG_STATE; 727 728 /* Read the status parameters from the connection control block */ 729 p_status->con_status = BNEP_STATUS_CONNECTED; 730 p_status->l2cap_cid = p_bcb->l2cap_cid; 731 p_status->rem_mtu_size = p_bcb->rem_mtu_size; 732 p_status->xmit_q_depth = GKI_queue_length(&p_bcb->xmit_q); 733 p_status->sent_num_filters = p_bcb->sent_num_filters; 734 p_status->sent_mcast_filters = p_bcb->sent_mcast_filters; 735 p_status->rcvd_num_filters = p_bcb->rcvd_num_filters; 736 p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters; 737 738 memcpy (p_status->rem_bda, p_bcb->rem_bda, BD_ADDR_LEN); 739 memcpy (&(p_status->src_uuid), &(p_bcb->src_uuid), sizeof (tBT_UUID)); 740 memcpy (&(p_status->dst_uuid), &(p_bcb->dst_uuid), sizeof (tBT_UUID)); 741 742 return BNEP_SUCCESS; 743#else 744 return (BNEP_IGNORE_CMD); 745#endif 746} 747 748 749