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 extern fixed_queue_t *btu_general_alarm_queue; 31 32 /******************************************************************************* 33 ** 34 ** Function BNEP_Init 35 ** 36 ** Description This function initializes the BNEP unit. It should be called 37 ** before accessing any other APIs to initialize the control block 38 ** 39 ** Returns void 40 ** 41 *******************************************************************************/ 42 void BNEP_Init (void) 43 { 44 memset (&bnep_cb, 0, sizeof (tBNEP_CB)); 45 46 #if defined(BNEP_INITIAL_TRACE_LEVEL) 47 bnep_cb.trace_level = BNEP_INITIAL_TRACE_LEVEL; 48 #else 49 bnep_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 50 #endif 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 *******************************************************************************/ 68 tBNEP_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 *******************************************************************************/ 103 void 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 *******************************************************************************/ 134 tBNEP_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 alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS, 212 bnep_conn_timer_timeout, p_bcb, 213 btu_general_alarm_queue); 214 } 215 216 *p_handle = p_bcb->handle; 217 return (BNEP_SUCCESS); 218 } 219 220 221 /******************************************************************************* 222 ** 223 ** Function BNEP_ConnectResp 224 ** 225 ** Description This function is called in responce to connection indication 226 ** 227 ** 228 ** Parameters: handle - handle given in the connection indication 229 ** resp - responce for the connection indication 230 ** 231 ** Returns BNEP_SUCCESS if connection started 232 ** BNEP_WRONG_HANDLE if the connection is not found 233 ** BNEP_WRONG_STATE if the responce is not expected 234 ** 235 *******************************************************************************/ 236 tBNEP_RESULT BNEP_ConnectResp (UINT16 handle, tBNEP_RESULT resp) 237 { 238 tBNEP_CONN *p_bcb; 239 UINT16 resp_code = BNEP_SETUP_CONN_OK; 240 241 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 242 return (BNEP_WRONG_HANDLE); 243 244 p_bcb = &(bnep_cb.bcb[handle - 1]); 245 246 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP || 247 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))) 248 return (BNEP_WRONG_STATE); 249 250 BNEP_TRACE_API ("BNEP_ConnectResp() for handle %d, responce %d", handle, resp); 251 252 /* Form appropriate responce based on profile responce */ 253 if (resp == BNEP_CONN_FAILED_SRC_UUID) resp_code = BNEP_SETUP_INVALID_SRC_UUID; 254 else if (resp == BNEP_CONN_FAILED_DST_UUID) resp_code = BNEP_SETUP_INVALID_DEST_UUID; 255 else if (resp == BNEP_CONN_FAILED_UUID_SIZE) resp_code = BNEP_SETUP_INVALID_UUID_SIZE; 256 else if (resp == BNEP_SUCCESS) resp_code = BNEP_SETUP_CONN_OK; 257 else resp_code = BNEP_SETUP_CONN_NOT_ALLOWED; 258 259 bnep_send_conn_responce (p_bcb, resp_code); 260 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 261 262 if (resp == BNEP_SUCCESS) 263 bnep_connected (p_bcb); 264 else if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) 265 { 266 /* Restore the original parameters */ 267 p_bcb->con_state = BNEP_STATE_CONNECTED; 268 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD); 269 270 memcpy ((UINT8 *)&(p_bcb->src_uuid), (UINT8 *)&(p_bcb->prv_src_uuid), sizeof (tBT_UUID)); 271 memcpy ((UINT8 *)&(p_bcb->dst_uuid), (UINT8 *)&(p_bcb->prv_dst_uuid), sizeof (tBT_UUID)); 272 } 273 274 /* Process remaining part of the setup message (extension headers) */ 275 if (p_bcb->p_pending_data) 276 { 277 UINT8 extension_present = TRUE, *p, ext_type; 278 UINT16 rem_len; 279 280 rem_len = p_bcb->p_pending_data->len; 281 p = (UINT8 *)(p_bcb->p_pending_data + 1) + p_bcb->p_pending_data->offset; 282 while (extension_present && p && rem_len) 283 { 284 ext_type = *p++; 285 extension_present = ext_type >> 7; 286 ext_type &= 0x7F; 287 288 /* if unknown extension present stop processing */ 289 if (ext_type) 290 break; 291 292 p = bnep_process_control_packet (p_bcb, p, &rem_len, TRUE); 293 } 294 295 osi_free_and_reset((void **)&p_bcb->p_pending_data); 296 } 297 return (BNEP_SUCCESS); 298 } 299 300 301 /******************************************************************************* 302 ** 303 ** Function BNEP_Disconnect 304 ** 305 ** Description This function is called to close the specified connection. 306 ** 307 ** Parameters: handle - handle of the connection 308 ** 309 ** Returns BNEP_SUCCESS if connection is disconnected 310 ** BNEP_WRONG_HANDLE if no connection is not found 311 ** 312 *******************************************************************************/ 313 tBNEP_RESULT BNEP_Disconnect (UINT16 handle) 314 { 315 tBNEP_CONN *p_bcb; 316 317 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 318 return (BNEP_WRONG_HANDLE); 319 320 p_bcb = &(bnep_cb.bcb[handle - 1]); 321 322 if (p_bcb->con_state == BNEP_STATE_IDLE) 323 return (BNEP_WRONG_HANDLE); 324 325 BNEP_TRACE_API ("BNEP_Disconnect() for handle %d", handle); 326 327 L2CA_DisconnectReq (p_bcb->l2cap_cid); 328 329 bnepu_release_bcb (p_bcb); 330 331 return (BNEP_SUCCESS); 332 } 333 334 335 /******************************************************************************* 336 ** 337 ** Function BNEP_WriteBuf 338 ** 339 ** Description This function sends data in a GKI buffer on BNEP connection 340 ** 341 ** Parameters: handle - handle of the connection to write 342 ** p_dest_addr - BD_ADDR/Ethernet addr of the destination 343 ** p_buf - pointer to address of buffer with data 344 ** protocol - protocol type of the packet 345 ** p_src_addr - (optional) BD_ADDR/ethernet address of the source 346 ** (should be NULL if it is local BD Addr) 347 ** fw_ext_present - forwarded extensions present 348 ** 349 ** Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 350 ** BNEP_MTU_EXCEDED - If the data length is greater than MTU 351 ** BNEP_IGNORE_CMD - If the packet is filtered out 352 ** BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 353 ** BNEP_SUCCESS - If written successfully 354 ** 355 *******************************************************************************/ 356 tBNEP_RESULT BNEP_WriteBuf (UINT16 handle, 357 UINT8 *p_dest_addr, 358 BT_HDR *p_buf, 359 UINT16 protocol, 360 UINT8 *p_src_addr, 361 BOOLEAN fw_ext_present) 362 { 363 tBNEP_CONN *p_bcb; 364 UINT8 *p_data; 365 366 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 367 { 368 osi_free(p_buf); 369 return (BNEP_WRONG_HANDLE); 370 } 371 372 p_bcb = &(bnep_cb.bcb[handle - 1]); 373 /* Check MTU size */ 374 if (p_buf->len > BNEP_MTU_SIZE) 375 { 376 BNEP_TRACE_ERROR ("BNEP_Write() length %d exceeded MTU %d", p_buf->len, BNEP_MTU_SIZE); 377 osi_free(p_buf); 378 return (BNEP_MTU_EXCEDED); 379 } 380 381 /* Check if the packet should be filtered out */ 382 p_data = (UINT8 *)(p_buf + 1) + p_buf->offset; 383 if (bnep_is_packet_allowed (p_bcb, p_dest_addr, protocol, fw_ext_present, p_data) != BNEP_SUCCESS) 384 { 385 /* 386 ** If packet is filtered and ext headers are present 387 ** drop the data and forward the ext headers 388 */ 389 if (fw_ext_present) 390 { 391 UINT8 ext, length; 392 UINT16 org_len, new_len; 393 /* parse the extension headers and findout the new packet len */ 394 org_len = p_buf->len; 395 new_len = 0; 396 do { 397 398 ext = *p_data++; 399 length = *p_data++; 400 p_data += length; 401 402 new_len += (length + 2); 403 404 if (new_len > org_len) 405 { 406 osi_free(p_buf); 407 return BNEP_IGNORE_CMD; 408 } 409 410 } while (ext & 0x80); 411 412 if (protocol != BNEP_802_1_P_PROTOCOL) 413 protocol = 0; 414 else 415 { 416 new_len += 4; 417 p_data[2] = 0; 418 p_data[3] = 0; 419 } 420 p_buf->len = new_len; 421 } 422 else 423 { 424 osi_free(p_buf); 425 return BNEP_IGNORE_CMD; 426 } 427 } 428 429 /* Check transmit queue */ 430 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) 431 { 432 osi_free(p_buf); 433 return (BNEP_Q_SIZE_EXCEEDED); 434 } 435 436 /* Build the BNEP header */ 437 bnepu_build_bnep_hdr (p_bcb, p_buf, protocol, p_src_addr, p_dest_addr, fw_ext_present); 438 439 /* Send the data or queue it up */ 440 bnepu_check_send_packet (p_bcb, p_buf); 441 442 return (BNEP_SUCCESS); 443 } 444 445 446 /******************************************************************************* 447 ** 448 ** Function BNEP_Write 449 ** 450 ** Description This function sends data over a BNEP connection 451 ** 452 ** Parameters: handle - handle of the connection to write 453 ** p_dest_addr - BD_ADDR/Ethernet addr of the destination 454 ** p_data - pointer to data start 455 ** protocol - protocol type of the packet 456 ** p_src_addr - (optional) BD_ADDR/ethernet address of the source 457 ** (should be NULL if it is local BD Addr) 458 ** fw_ext_present - forwarded extensions present 459 ** 460 ** Returns: BNEP_WRONG_HANDLE - if passed handle is not valid 461 ** BNEP_MTU_EXCEDED - If the data length is greater than MTU 462 ** BNEP_IGNORE_CMD - If the packet is filtered out 463 ** BNEP_Q_SIZE_EXCEEDED - If the Tx Q is full 464 ** BNEP_NO_RESOURCES - If not able to allocate a buffer 465 ** BNEP_SUCCESS - If written successfully 466 ** 467 *******************************************************************************/ 468 tBNEP_RESULT BNEP_Write (UINT16 handle, 469 UINT8 *p_dest_addr, 470 UINT8 *p_data, 471 UINT16 len, 472 UINT16 protocol, 473 UINT8 *p_src_addr, 474 BOOLEAN fw_ext_present) 475 { 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 (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) 536 return (BNEP_Q_SIZE_EXCEEDED); 537 538 /* Get a buffer to copy the data into */ 539 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BNEP_BUF_SIZE); 540 541 p_buf->len = len; 542 p_buf->offset = BNEP_MINIMUM_OFFSET; 543 p = (UINT8 *)(p_buf + 1) + BNEP_MINIMUM_OFFSET; 544 545 memcpy (p, p_data, len); 546 547 /* Build the BNEP header */ 548 bnepu_build_bnep_hdr (p_bcb, p_buf, protocol, p_src_addr, p_dest_addr, fw_ext_present); 549 550 /* Send the data or queue it up */ 551 bnepu_check_send_packet (p_bcb, p_buf); 552 553 return (BNEP_SUCCESS); 554 } 555 556 557 /******************************************************************************* 558 ** 559 ** Function BNEP_SetProtocolFilters 560 ** 561 ** Description This function sets the protocol filters on peer device 562 ** 563 ** Parameters: handle - Handle for the connection 564 ** num_filters - total number of filter ranges 565 ** p_start_array - Array of beginings of all protocol ranges 566 ** p_end_array - Array of ends of all protocol ranges 567 ** 568 ** Returns BNEP_WRONG_HANDLE - if the connection handle is not valid 569 ** BNEP_SET_FILTER_FAIL - if the connection is in wrong state 570 ** BNEP_TOO_MANY_FILTERS - if too many filters 571 ** BNEP_SUCCESS - if request sent successfully 572 ** 573 *******************************************************************************/ 574 tBNEP_RESULT BNEP_SetProtocolFilters (UINT16 handle, 575 UINT16 num_filters, 576 UINT16 *p_start_array, 577 UINT16 *p_end_array) 578 { 579 UINT16 xx; 580 tBNEP_CONN *p_bcb; 581 582 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 583 return (BNEP_WRONG_HANDLE); 584 585 p_bcb = &(bnep_cb.bcb[handle - 1]); 586 587 /* Check the connection state */ 588 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 589 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 590 return (BNEP_WRONG_STATE); 591 592 /* Validate the parameters */ 593 if (num_filters && (!p_start_array || !p_end_array)) 594 return (BNEP_SET_FILTER_FAIL); 595 596 if (num_filters > BNEP_MAX_PROT_FILTERS) 597 return (BNEP_TOO_MANY_FILTERS); 598 599 /* Fill the filter values in connnection block */ 600 for (xx = 0; xx < num_filters; xx++) 601 { 602 p_bcb->sent_prot_filter_start[xx] = *p_start_array++; 603 p_bcb->sent_prot_filter_end[xx] = *p_end_array++; 604 } 605 606 p_bcb->sent_num_filters = num_filters; 607 608 bnepu_send_peer_our_filters (p_bcb); 609 610 return (BNEP_SUCCESS); 611 } 612 613 614 /******************************************************************************* 615 ** 616 ** Function BNEP_SetMulticastFilters 617 ** 618 ** Description This function sets the filters for multicast addresses for BNEP. 619 ** 620 ** Parameters: handle - Handle for the connection 621 ** num_filters - total number of filter ranges 622 ** p_start_array - Pointer to sequence of beginings of all 623 ** multicast address ranges 624 ** p_end_array - Pointer to sequence of ends of all 625 ** multicast address ranges 626 ** 627 ** Returns BNEP_WRONG_HANDLE - if the connection handle is not valid 628 ** BNEP_SET_FILTER_FAIL - if the connection is in wrong state 629 ** BNEP_TOO_MANY_FILTERS - if too many filters 630 ** BNEP_SUCCESS - if request sent successfully 631 ** 632 *******************************************************************************/ 633 tBNEP_RESULT BNEP_SetMulticastFilters (UINT16 handle, 634 UINT16 num_filters, 635 UINT8 *p_start_array, 636 UINT8 *p_end_array) 637 { 638 UINT16 xx; 639 tBNEP_CONN *p_bcb; 640 641 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 642 return (BNEP_WRONG_HANDLE); 643 644 p_bcb = &(bnep_cb.bcb[handle - 1]); 645 646 /* Check the connection state */ 647 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 648 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 649 return (BNEP_WRONG_STATE); 650 651 /* Validate the parameters */ 652 if (num_filters && (!p_start_array || !p_end_array)) 653 return (BNEP_SET_FILTER_FAIL); 654 655 if (num_filters > BNEP_MAX_MULTI_FILTERS) 656 return (BNEP_TOO_MANY_FILTERS); 657 658 /* Fill the multicast filter values in connnection block */ 659 for (xx = 0; xx < num_filters; xx++) 660 { 661 memcpy (p_bcb->sent_mcast_filter_start[xx], p_start_array, BD_ADDR_LEN); 662 memcpy (p_bcb->sent_mcast_filter_end[xx], p_end_array, BD_ADDR_LEN); 663 664 p_start_array += BD_ADDR_LEN; 665 p_end_array += BD_ADDR_LEN; 666 } 667 668 p_bcb->sent_mcast_filters = num_filters; 669 670 bnepu_send_peer_our_multi_filters (p_bcb); 671 672 return (BNEP_SUCCESS); 673 } 674 675 /******************************************************************************* 676 ** 677 ** Function BNEP_SetTraceLevel 678 ** 679 ** Description This function sets the trace level for BNEP. If called with 680 ** a value of 0xFF, it simply reads the current trace level. 681 ** 682 ** Returns the new (current) trace level 683 ** 684 *******************************************************************************/ 685 UINT8 BNEP_SetTraceLevel (UINT8 new_level) 686 { 687 if (new_level != 0xFF) 688 bnep_cb.trace_level = new_level; 689 690 return (bnep_cb.trace_level); 691 } 692 693 694 /******************************************************************************* 695 ** 696 ** Function BNEP_GetStatus 697 ** 698 ** Description This function gets the status information for BNEP connection 699 ** 700 ** Returns BNEP_SUCCESS - if the status is available 701 ** BNEP_NO_RESOURCES - if no structure is passed for output 702 ** BNEP_WRONG_HANDLE - if the handle is invalid 703 ** BNEP_WRONG_STATE - if not in connected state 704 ** 705 *******************************************************************************/ 706 tBNEP_RESULT BNEP_GetStatus (UINT16 handle, tBNEP_STATUS *p_status) 707 { 708 #if (defined (BNEP_SUPPORTS_STATUS_API) && BNEP_SUPPORTS_STATUS_API == TRUE) 709 tBNEP_CONN *p_bcb; 710 711 if (!p_status) 712 return BNEP_NO_RESOURCES; 713 714 if ((!handle) || (handle > BNEP_MAX_CONNECTIONS)) 715 return (BNEP_WRONG_HANDLE); 716 717 p_bcb = &(bnep_cb.bcb[handle - 1]); 718 719 memset (p_status, 0, sizeof (tBNEP_STATUS)); 720 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && 721 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) 722 return BNEP_WRONG_STATE; 723 724 /* Read the status parameters from the connection control block */ 725 p_status->con_status = BNEP_STATUS_CONNECTED; 726 p_status->l2cap_cid = p_bcb->l2cap_cid; 727 p_status->rem_mtu_size = p_bcb->rem_mtu_size; 728 p_status->xmit_q_depth = fixed_queue_length(p_bcb->xmit_q); 729 p_status->sent_num_filters = p_bcb->sent_num_filters; 730 p_status->sent_mcast_filters = p_bcb->sent_mcast_filters; 731 p_status->rcvd_num_filters = p_bcb->rcvd_num_filters; 732 p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters; 733 734 memcpy (p_status->rem_bda, p_bcb->rem_bda, BD_ADDR_LEN); 735 memcpy (&(p_status->src_uuid), &(p_bcb->src_uuid), sizeof (tBT_UUID)); 736 memcpy (&(p_status->dst_uuid), &(p_bcb->dst_uuid), sizeof (tBT_UUID)); 737 738 return BNEP_SUCCESS; 739 #else 740 return (BNEP_IGNORE_CMD); 741 #endif 742 } 743 744 745