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